From 7170543e8012250b7643a960b54cce7fd6d3a1e9 Mon Sep 17 00:00:00 2001
From: Ramanpreet Nara
Date: Wed, 8 Nov 2017 10:27:39 -0800
Subject: [PATCH 01/50] Make direction-aware borders work with APIs >= 17
Reviewed By: achen1
Differential Revision: D6189497
fbshipit-source-id: 848ca35540c5a4eb1581e0b7c39f8fa880540317
---
.../view/ReactViewBackgroundDrawable.java | 38 ++++++++++++++-----
.../react/views/view/ReactViewGroup.java | 10 ++---
2 files changed, 34 insertions(+), 14 deletions(-)
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundDrawable.java b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundDrawable.java
index 477526d86acf5f..b32855b1450625 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundDrawable.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundDrawable.java
@@ -109,6 +109,7 @@ private static enum BorderStyle {
private @Nullable float[] mBorderCornerRadii;
private final Context mContext;
+ private int mLayoutDirection;
public enum BorderRadiusLocation {
TOP_LEFT,
@@ -290,6 +291,25 @@ public void setColor(int color) {
invalidateSelf();
}
+ /** Similar to Drawable.getLayoutDirection, but available in APIs < 23. */
+ public int getResolvedLayoutDirection() {
+ return mLayoutDirection;
+ }
+
+ /** Similar to Drawable.setLayoutDirection, but available in APIs < 23. */
+ public boolean setResolvedLayoutDirection(int layoutDirection) {
+ if (mLayoutDirection != layoutDirection) {
+ mLayoutDirection = layoutDirection;
+ return onResolvedLayoutDirectionChanged(layoutDirection);
+ }
+ return false;
+ }
+
+ /** Similar to Drawable.onLayoutDirectionChanged, but available in APIs < 23. */
+ public boolean onResolvedLayoutDirectionChanged(int layoutDirection) {
+ return false;
+ }
+
@VisibleForTesting
public int getColor() {
return mColor;
@@ -323,8 +343,8 @@ private void drawRoundedBackgroundWithBorders(Canvas canvas) {
int colorRight = getBorderColor(Spacing.RIGHT);
int colorBottom = getBorderColor(Spacing.BOTTOM);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- final boolean isRTL = getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ final boolean isRTL = getResolvedLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
int colorStart = getBorderColor(Spacing.START);
int colorEnd = getBorderColor(Spacing.END);
@@ -478,13 +498,13 @@ private void updatePath() {
float bottomRightRadius =
getBorderRadiusOrDefaultTo(borderRadius, BorderRadiusLocation.BOTTOM_RIGHT);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- final boolean isRTL = getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ final boolean isRTL = getResolvedLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
float topStartRadius = getBorderRadius(BorderRadiusLocation.TOP_START);
float topEndRadius = getBorderRadius(BorderRadiusLocation.TOP_END);
float bottomStartRadius = getBorderRadius(BorderRadiusLocation.BOTTOM_START);
float bottomEndRadius = getBorderRadius(BorderRadiusLocation.BOTTOM_END);
-
+
if (I18nUtil.getInstance().doLeftAndRightSwapInRTL(mContext)) {
if (YogaConstants.isUndefined(topStartRadius)) {
topStartRadius = topLeftRadius;
@@ -930,8 +950,8 @@ private void drawRectangularBackgroundWithBorders(Canvas canvas) {
int colorRight = getBorderColor(Spacing.RIGHT);
int colorBottom = getBorderColor(Spacing.BOTTOM);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- final boolean isRTL = getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ final boolean isRTL = getResolvedLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
int colorStart = getBorderColor(Spacing.START);
int colorEnd = getBorderColor(Spacing.END);
@@ -1140,8 +1160,8 @@ public RectF getDirectionAwareBorderInsets() {
float borderLeftWidth = getBorderWidthOrDefaultTo(borderWidth, Spacing.LEFT);
float borderRightWidth = getBorderWidthOrDefaultTo(borderWidth, Spacing.RIGHT);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && mBorderWidth != null) {
- final boolean isRTL = getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && mBorderWidth != null) {
+ final boolean isRTL = getResolvedLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
float borderStartWidth = mBorderWidth.getRaw(Spacing.START);
float borderEndWidth = mBorderWidth.getRaw(Spacing.END);
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java
index 592f328e9663ff..8e80168a33b29e 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java
@@ -129,9 +129,9 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
@Override
public void onRtlPropertiesChanged(int layoutDirection) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (mReactBackgroundDrawable != null) {
- mReactBackgroundDrawable.setLayoutDirection(mLayoutDirection);
+ mReactBackgroundDrawable.setResolvedLayoutDirection(mLayoutDirection);
}
}
}
@@ -589,12 +589,12 @@ private ReactViewBackgroundDrawable getOrCreateReactViewBackground() {
updateBackgroundDrawable(layerDrawable);
}
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
mLayoutDirection =
I18nUtil.getInstance().isRTL(getContext())
? LAYOUT_DIRECTION_RTL
: LAYOUT_DIRECTION_LTR;
- mReactBackgroundDrawable.setLayoutDirection(mLayoutDirection);
+ mReactBackgroundDrawable.setResolvedLayoutDirection(mLayoutDirection);
}
}
return mReactBackgroundDrawable;
@@ -671,7 +671,7 @@ protected void dispatchDraw(Canvas canvas) {
mReactBackgroundDrawable.getBorderRadiusOrDefaultTo(
borderRadius, ReactViewBackgroundDrawable.BorderRadiusLocation.BOTTOM_RIGHT);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
final boolean isRTL = mLayoutDirection == View.LAYOUT_DIRECTION_RTL;
float topStartBorderRadius =
mReactBackgroundDrawable.getBorderRadius(
From 1d6ce2311f6a51821b33c5473414d70c8bd34425 Mon Sep 17 00:00:00 2001
From: Yujie Liu
Date: Wed, 8 Nov 2017 12:00:40 -0800
Subject: [PATCH 02/50] Rename scaledAssetURLScript function to
scaledAssetURLNearBundle
Reviewed By: zahanm
Differential Revision: D6272905
fbshipit-source-id: bff661fcadd73a5400cea422a8a5ac5db34717a8
---
Libraries/Image/AssetSourceResolver.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Libraries/Image/AssetSourceResolver.js b/Libraries/Image/AssetSourceResolver.js
index ae759c719b84e8..2183d1a98904d2 100644
--- a/Libraries/Image/AssetSourceResolver.js
+++ b/Libraries/Image/AssetSourceResolver.js
@@ -79,7 +79,7 @@ class AssetSourceResolver {
this.drawableFolderInBundle() :
this.resourceIdentifierWithoutScale();
} else {
- return this.scaledAssetURLInScript();
+ return this.scaledAssetURLNearBundle();
}
}
@@ -104,10 +104,10 @@ class AssetSourceResolver {
}
/**
- * Resolves to where the script is running from, with a scaled asset filename
+ * Resolves to where the bundle is running from, with a scaled asset filename
* E.g. 'file:///sdcard/bundle/assets/AwesomeModule/icon@2x.png'
*/
- scaledAssetURLInScript(): ResolvedAssetSource {
+ scaledAssetURLNearBundle(): ResolvedAssetSource {
const path = this.jsbundleUrl || 'file://';
return this.fromSource(path + getScaledAssetPath(this.asset));
}
From 354e1cb5088a43fd4116504a34a65ca53c4de71b Mon Sep 17 00:00:00 2001
From: Erik Behrends
Date: Wed, 8 Nov 2017 12:07:30 -0800
Subject: [PATCH 03/50] Fix missing return in example
Summary:
Found this minor issue while reading the docs.
n/a
[DOCS] [BUGFIX] [Libraries/Text/Text.js] - Add return to example
Closes https://github.com/facebook/react-native/pull/16752
Differential Revision: D6274215
Pulled By: hramos
fbshipit-source-id: ef735eb9179ab69d2ed1bc4a8b5e921d42d88fb0
---
Libraries/Text/Text.js | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/Libraries/Text/Text.js b/Libraries/Text/Text.js
index 92c382b9651060..7f9907e76e26ad 100644
--- a/Libraries/Text/Text.js
+++ b/Libraries/Text/Text.js
@@ -243,11 +243,13 @@ const viewConfig = {
* ```javascript
* class MyAppHeaderText extends Component {
* render() {
- *
- *
- * {this.props.children}
- *
- *
+ * return (
+ *
+ *
+ * {this.props.children}
+ *
+ *
+ * );
* }
* }
* ```
From e9393f694d8f0d0190a3576fd65a65f747f8cce2 Mon Sep 17 00:00:00 2001
From: Rafael Oleza
Date: Wed, 8 Nov 2017 12:34:00 -0800
Subject: [PATCH 04/50] Remove old bundler code from Server class
Reviewed By: mjesun
Differential Revision: D6255868
fbshipit-source-id: 74695129199c8be43e13c97f2ae2ca2c03b801eb
---
.../__tests__/getInverseDependencies-test.js | 57 ---
local-cli/server/util/attachHMRServer.js | 459 ------------------
.../server/util/getInverseDependencies.js | 70 ---
3 files changed, 586 deletions(-)
delete mode 100644 local-cli/server/util/__tests__/getInverseDependencies-test.js
delete mode 100644 local-cli/server/util/attachHMRServer.js
delete mode 100644 local-cli/server/util/getInverseDependencies.js
diff --git a/local-cli/server/util/__tests__/getInverseDependencies-test.js b/local-cli/server/util/__tests__/getInverseDependencies-test.js
deleted file mode 100644
index 5936f3e113b8dd..00000000000000
--- a/local-cli/server/util/__tests__/getInverseDependencies-test.js
+++ /dev/null
@@ -1,57 +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.
- *
- * @emails oncall+javascript_foundation
- */
-'use strict';
-
-jest.dontMock('../getInverseDependencies');
-
-const getInverseDependencies = require('../getInverseDependencies');
-
-describe('getInverseDependencies', () => {
- it('', () => {
- const module1 = createModule('module1', ['module2', 'module3']);
- const module2 = createModule('module2', ['module3', 'module4']);
- const module3 = createModule('module3', ['module4']);
- const module4 = createModule('module4', []);
-
- const modulePairs = {
- 'module1': [['module2', module2], ['module3', module3]],
- 'module2': [['module3', module3], ['module4', module4]],
- 'module3': [['module4', module4]],
- 'module4': [],
- };
-
- const resolutionResponse = {
- dependencies: [module1, module2, module3, module4],
- getResolvedDependencyPairs: module => {
- return modulePairs[module.hash()];
- },
- };
-
- const dependencies = getInverseDependencies(resolutionResponse);
- const actual = // jest can't compare maps and sets
- Array.from(dependencies.entries())
- .map(([key, value]) => [key, Array.from(value)]);
-
- expect(actual).toEqual([
- [module2, [module1]],
- [module3, [module1, module2]],
- [module4, [module2, module3]],
- ]);
- });
-});
-
-function createModule(name, dependencies) {
- return {
- hash: () => name,
- getName: () => Promise.resolve(name),
- getDependencies: () => Promise.resolve(dependencies),
- };
-}
diff --git a/local-cli/server/util/attachHMRServer.js b/local-cli/server/util/attachHMRServer.js
deleted file mode 100644
index 184eb78febded2..00000000000000
--- a/local-cli/server/util/attachHMRServer.js
+++ /dev/null
@@ -1,459 +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.
- *
- * @flow
- */
-
-'use strict';
-
-const getInverseDependencies = require('./getInverseDependencies');
-const querystring = require('querystring');
-const url = require('url');
-
-import type {ResolutionResponse} from './getInverseDependencies';
-import type {Server as HTTPServer} from 'http';
-import type {Server as HTTPSServer} from 'https';
-import type {Client as WebSocketClient} from 'ws';
-
-const blacklist = [
- 'Libraries/Utilities/HMRClient.js',
-];
-
-type HMRBundle = {
- getModulesIdsAndCode(): Array<{id: string, code: string}>,
- getSourceMappingURLs(): Array,
- getSourceURLs(): Array,
- isEmpty(): boolean,
-};
-
-type DependencyOptions = {|
- +dev: boolean,
- +entryFile: string,
- +hot: boolean,
- +minify: boolean,
- +platform: ?string,
- +recursive: boolean,
- +rootEntryFile: string,
- +bundlingOptions?: Object,
-|};
-
-/**
- * This is a subset of the actual `metro-bundler`'s `Server` class,
- * without all the stuff we don't need to know about. This allows us to use
- * `attachHMRServer` with different versions of `metro-bundler` as long as
- * this specific contract is maintained.
- */
-type PackagerServer = {
- buildBundleForHMR(
- options: {platform: ?string},
- host: string,
- port: number,
- ): Promise,
- getDependencies(options: DependencyOptions): Promise>,
- getModuleForPath(entryFile: string): Promise,
- getShallowDependencies(options: DependencyOptions): Promise>,
- setHMRFileChangeListener(listener: ?(type: string, filePath: string) => mixed): void,
-};
-
-type HMROptions = {
- httpServer: HTTPServer | HTTPSServer,
- packagerServer: PackagerServer,
- path: string,
-};
-
-type Moduleish = {
- getName(): string,
- isAsset(): boolean,
- isJSON(): boolean,
- path: string,
-};
-
-/**
- * Attaches a WebSocket based connection to the Packager to expose
- * Hot Module Replacement updates to the simulator.
- */
-function attachHMRServer(
- {httpServer, path, packagerServer}: HMROptions,
-) {
- type Client = {|
- ws: WebSocketClient,
- platform: string,
- bundleEntry: string,
- dependenciesCache: Array,
- dependenciesModulesCache: {[mixed]: TModule},
- shallowDependencies: {[string]: Array},
- inverseDependenciesCache: mixed,
- |};
-
- const clients: Set = new Set();
-
- function disconnect(client: Client) {
- clients.delete(client);
-
- // If there are no clients connected, stop listenig for file changes
- if (clients.size === 0) {
- packagerServer.setHMRFileChangeListener(null);
- }
- }
-
- // For the give platform and entry file, returns a promise with:
- // - The full list of dependencies.
- // - The shallow dependencies each file on the dependency list has
- // - Inverse shallow dependencies map
- async function getDependencies(platform: string, bundleEntry: string): Promise<{
- dependenciesCache: Array,
- dependenciesModulesCache: {[mixed]: TModule},
- shallowDependencies: {[string]: Array},
- inverseDependenciesCache: mixed,
- /* $FlowFixMe(>=0.54.0 site=react_native_fb,react_native_oss) This comment
- * suppresses an error found when Flow v0.54 was deployed. To see the error
- * delete this comment and run Flow. */
- resolutionResponse: ResolutionResponse,
- }> {
- const response = await packagerServer.getDependencies({
- dev: true,
- entryFile: bundleEntry,
- rootEntryFile: bundleEntry,
- hot: true,
- minify: false,
- platform: platform,
- recursive: true,
- });
-
- /* $FlowFixMe: getModuleId might be null */
- const {getModuleId}: {getModuleId: () => number} = response;
-
- // for each dependency builds the object:
- // `{path: '/a/b/c.js', deps: ['modA', 'modB', ...]}`
- const deps: Array<{
- path: string,
- name?: string,
- deps: Array,
- }> = await Promise.all(response.dependencies.map(async (dep: TModule) => {
- const depName = dep.getName();
-
- if (dep.isAsset() || dep.isJSON()) {
- return {path: dep.path, deps: []};
- }
- const dependencies = await packagerServer.getShallowDependencies({
- dev: true,
- entryFile: dep.path,
- rootEntryFile: bundleEntry,
- hot: true,
- minify: false,
- platform: platform,
- recursive: true,
- bundlingOptions: response.options,
- });
-
- return {
- path: dep.path,
- name: depName,
- deps: dependencies,
- };
- }));
-
- // list with all the dependencies' filenames the bundle entry has
- const dependenciesCache = response.dependencies.map(dep => dep.path);
-
- // map from module name to path
- const moduleToFilenameCache = Object.create(null);
- deps.forEach(dep => {
- /* $FlowFixMe: `name` could be null, but `deps` would be as well. */
- moduleToFilenameCache[dep.name] = dep.path;
- });
-
- // map that indicates the shallow dependency each file included on the
- // bundle has
- const shallowDependencies = Object.create(null);
- deps.forEach(dep => {
- shallowDependencies[dep.path] = dep.deps;
- });
-
- // map from module name to the modules' dependencies the bundle entry
- // has
- const dependenciesModulesCache = Object.create(null);
- response.dependencies.forEach(dep => {
- dependenciesModulesCache[getModuleId(dep)] = dep;
- });
-
- const inverseDependenciesCache = Object.create(null);
- const inverseDependencies = getInverseDependencies(response);
- for (const [module, dependents] of inverseDependencies) {
- inverseDependenciesCache[getModuleId(module)] =
- Array.from(dependents).map(getModuleId);
- }
-
- /* $FlowFixMe(>=0.56.0 site=react_native_oss) This comment suppresses an
- * error found when Flow v0.56 was deployed. To see the error delete this
- * comment and run Flow. */
- /* $FlowFixMe(>=0.56.0 site=react_native_fb,react_native_oss) This comment
- * suppresses an error found when Flow v0.56 was deployed. To see the error
- * delete this comment and run Flow. */
- return {
- dependenciesCache,
- dependenciesModulesCache,
- shallowDependencies,
- inverseDependenciesCache,
- resolutionResponse: response,
- };
- }
-
- async function prepareResponse(
- client: Client,
- filename: string,
- ): Promise {
- try {
- const bundle = await generateBundle(client, filename);
-
- if (!bundle || bundle.isEmpty()) {
- return;
- }
-
- return {
- type: 'update',
- body: {
- modules: bundle.getModulesIdsAndCode(),
- inverseDependencies: client.inverseDependenciesCache,
- sourceURLs: bundle.getSourceURLs(),
- sourceMappingURLs: bundle.getSourceMappingURLs(),
- },
- };
- } catch (error) {
- // send errors to the client instead of killing packager server
- let body;
- if (error.type === 'TransformError' ||
- error.type === 'NotFoundError' ||
- error.type === 'UnableToResolveError') {
- body = {
- type: error.type,
- description: error.description,
- filename: error.filename,
- lineNumber: error.lineNumber,
- };
- } else {
- console.error(error.stack || error);
- body = {
- type: 'InternalError',
- description: 'react-packager has encountered an internal error, ' +
- 'please check your terminal error output for more details',
- };
- }
-
- return {type: 'error', body};
- }
- }
-
- async function generateBundle(
- client: Client,
- filename: string,
- ): Promise {
- // If the main file is an asset, do not generate a bundle.
- const moduleToUpdate = await packagerServer.getModuleForPath(filename);
- if (moduleToUpdate.isAsset()) {
- return;
- }
-
- const deps = await packagerServer.getShallowDependencies({
- dev: true,
- minify: false,
- entryFile: filename,
- rootEntryFile: client.bundleEntry,
- hot: true,
- platform: client.platform,
- recursive: true,
- });
-
- // if the file dependencies have change we need to invalidate the
- // dependencies caches because the list of files we need to send
- // to the client may have changed
- const oldDependencies = client.shallowDependencies[filename];
-
- let resolutionResponse;
-
- if (arrayEquals(deps, oldDependencies)) {
- // Need to create a resolution response to pass to the bundler
- // to process requires after transform. By providing a
- // specific response we can compute a non recursive one which
- // is the least we need and improve performance.
- const response = await packagerServer.getDependencies({
- dev: true,
- entryFile: filename,
- rootEntryFile: client.bundleEntry,
- hot: true,
- minify: false,
- platform: client.platform,
- recursive: true,
- });
-
- resolutionResponse = await response.copy({
- dependencies: [moduleToUpdate]},
- );
- } else {
- // if there're new dependencies compare the full list of
- // dependencies we used to have with the one we now have
- const {
- dependenciesCache: depsCache,
- dependenciesModulesCache: depsModulesCache,
- shallowDependencies: shallowDeps,
- inverseDependenciesCache: inverseDepsCache,
- resolutionResponse: myResolutionReponse,
- } = await getDependencies(client.platform, client.bundleEntry);
-
- // build list of modules for which we'll send HMR updates
- const modulesToUpdate = [moduleToUpdate];
- Object.keys(depsModulesCache).forEach(module => {
- if (!client.dependenciesModulesCache[module]) {
- modulesToUpdate.push(depsModulesCache[module]);
- }
- });
-
- // Need to send modules to the client in an order it can
- // process them: if a new dependency graph was uncovered
- // because a new dependency was added, the file that was
- // changed, which is the root of the dependency tree that
- // will be sent, needs to be the last module that gets
- // processed. Reversing the new modules makes sense
- // because we get them through the resolver which returns
- // a BFS ordered list.
- modulesToUpdate.reverse();
-
- // invalidate caches
- client.dependenciesCache = depsCache;
- client.dependenciesModulesCache = depsModulesCache;
- client.shallowDependencies = shallowDeps;
- client.inverseDependenciesCache = inverseDepsCache;
-
- resolutionResponse = await myResolutionReponse.copy({
- dependencies: modulesToUpdate,
- });
- }
-
- // make sure the file was modified is part of the bundle
- if (!client.shallowDependencies[filename]) {
- return;
- }
-
- const httpServerAddress = httpServer.address();
-
- // Sanitize the value from the HTTP server
- let packagerHost = 'localhost';
- if (httpServer.address().address &&
- httpServer.address().address !== '::' &&
- httpServer.address().address !== '') {
- packagerHost = httpServerAddress.address;
- }
-
- const bundle: HMRBundle = await packagerServer.buildBundleForHMR(
- {
- entryFile: client.bundleEntry,
- platform: client.platform,
- resolutionResponse,
- },
- packagerHost,
- httpServerAddress.port,
- );
-
- return bundle;
- }
-
- function handleFileChange(
- type: string,
- filename: string,
- ): void {
- clients.forEach(
- client => sendFileChangeToClient(client, type, filename),
- );
- }
-
- async function sendFileChangeToClient(
- client: Client,
- type: string,
- filename: string,
- ): Promise {
- const blacklisted = blacklist.find(
- blacklistedPath => filename.indexOf(blacklistedPath) !== -1,
- );
- if (blacklisted) {
- return;
- }
-
- if (clients.has(client)) {
- client.ws.send(JSON.stringify({type: 'update-start'}));
- }
-
- if (type !== 'delete') {
- const response = await prepareResponse(client, filename);
-
- if (response && clients.has(client)) {
- client.ws.send(JSON.stringify(response));
- }
- }
-
- if (clients.has(client)) {
- client.ws.send(JSON.stringify({type: 'update-done'}));
- }
- }
-
- /* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an
- * error found when Flow v0.54 was deployed. To see the error delete this
- * comment and run Flow. */
- const WebSocketServer = require('ws').Server;
- const wss = new WebSocketServer({
- server: httpServer,
- path: path,
- });
-
- wss.on('connection', async ws => {
- /* $FlowFixMe: url might be null */
- const params = querystring.parse(url.parse(ws.upgradeReq.url).query);
-
- const {
- dependenciesCache,
- dependenciesModulesCache,
- shallowDependencies,
- inverseDependenciesCache,
- } = await getDependencies(params.platform, params.bundleEntry);
-
- const client = {
- ws,
- platform: params.platform,
- bundleEntry: params.bundleEntry,
- dependenciesCache,
- dependenciesModulesCache,
- shallowDependencies,
- inverseDependenciesCache,
- };
- clients.add(client);
-
- // If this is the first client connecting, start listening to file changes
- if (clients.size === 1) {
- packagerServer.setHMRFileChangeListener(handleFileChange);
- }
-
- client.ws.on('error', e => {
- console.error('[Hot Module Replacement] Unexpected error', e);
- disconnect(client);
- });
-
- client.ws.on('close', () => disconnect(client));
- });
-}
-
-function arrayEquals(arrayA: Array, arrayB: Array): boolean {
- arrayA = arrayA || [];
- arrayB = arrayB || [];
- return (
- arrayA.length === arrayB.length &&
- arrayA.every((element, index) => {
- return element === arrayB[index];
- })
- );
-}
-
-module.exports = attachHMRServer;
diff --git a/local-cli/server/util/getInverseDependencies.js b/local-cli/server/util/getInverseDependencies.js
deleted file mode 100644
index 927af924672998..00000000000000
--- a/local-cli/server/util/getInverseDependencies.js
+++ /dev/null
@@ -1,70 +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.
- *
- * @flow
- * @format
- */
-
-'use strict';
-
-/**
- * This is a subset of the actual `metro-bundler`'s `ResolutionResponse` class,
- * without all the stuff we don't need to know about. This allows us to use
- * `getInverseDependencies` with different versions of `metro-bundler`.
- */
-export type ResolutionResponse = {
- copy(data: {
- dependencies?: Array,
- mainModuleId?: number,
- mocks?: mixed,
- }): ResolutionResponse,
- dependencies: Array,
- getResolvedDependencyPairs(
- module: TModule,
- ): $ReadOnlyArray<[string, TModule]>,
- options: Object,
-};
-
-function resolveModuleRequires(
- resolutionResponse: ResolutionResponse,
- module: TModule,
-): Array {
- const pairs = resolutionResponse.getResolvedDependencyPairs(module);
- return pairs ? pairs.map(([, dependencyModule]) => dependencyModule) : [];
-}
-
-function getModuleDependents(
- cache: Map>,
- module: TModule,
-): Set {
- let dependents = cache.get(module);
- if (!dependents) {
- dependents = new Set();
- cache.set(module, dependents);
- }
- return dependents;
-}
-
-/**
- * Returns an object that indicates in which module each module is required.
- */
-function getInverseDependencies(
- resolutionResponse: ResolutionResponse,
-): Map> {
- const cache = new Map();
-
- resolutionResponse.dependencies.forEach(module => {
- resolveModuleRequires(resolutionResponse, module).forEach(dependency => {
- getModuleDependents(cache, dependency).add(module);
- });
- });
-
- return cache;
-}
-
-module.exports = getInverseDependencies;
From ae5ef653cbc4c03fe5edb5d4b0002e38cbb6f458 Mon Sep 17 00:00:00 2001
From: Yujie Liu
Date: Thu, 9 Nov 2017 09:01:21 -0800
Subject: [PATCH 05/50] Rename bundleSource to embeddedBundle
Reviewed By: fromcelticpark
Differential Revision: D6274101
fbshipit-source-id: f62da158d165cb3ce4a510ebc4eed24a8a719381
---
React/Base/RCTBridge.h | 4 ++--
React/Base/RCTBridge.m | 6 +++---
React/Base/RCTBridgeDelegate.h | 4 ++--
React/CxxBridge/RCTCxxBridge.mm | 6 +++---
React/Modules/RCTSourceCode.m | 2 +-
5 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/React/Base/RCTBridge.h b/React/Base/RCTBridge.h
index 9a5fa5cd1f749d..450a0d0e38a104 100644
--- a/React/Base/RCTBridge.h
+++ b/React/Base/RCTBridge.h
@@ -172,9 +172,9 @@ RCT_EXTERN NSString *RCTBridgeModuleNameForClass(Class bridgeModuleClass);
@property (nonatomic, strong, readonly) NSURL *bundleURL;
/**
- * URL of the original script (not necessarily loaded) of the bridge.
+ * URL of the embedded bundle of the bridge.
*/
-@property (nonatomic, strong, readonly) NSURL *bundledSourceURL;
+@property (nonatomic, strong, readonly) NSURL *embeddedBundleURL;
/**
* The class of the executor currently being used. Changes to this value will
diff --git a/React/Base/RCTBridge.m b/React/Base/RCTBridge.m
index b69ea1d9fd5ae3..a8cef88c7bf4d9 100644
--- a/React/Base/RCTBridge.m
+++ b/React/Base/RCTBridge.m
@@ -329,9 +329,9 @@ - (void)setUp
// Sanitize the bundle URL
_bundleURL = [RCTConvert NSURL:_bundleURL.absoluteString];
- if ([self.delegate respondsToSelector:@selector(bundledSourceURLForBridge:)]) {
- _bundledSourceURL = [self.delegate bundledSourceURLForBridge:self];
- _bundledSourceURL = [RCTConvert NSURL:_bundledSourceURL.absoluteString];
+ if ([self.delegate respondsToSelector:@selector(embeddedBundleURLForBridge:)]) {
+ _embeddedBundleURL = [self.delegate embeddedBundleURLForBridge:self];
+ _embeddedBundleURL = [RCTConvert NSURL:_embeddedBundleURL.absoluteString];
}
self.batchedBridge = [[bridgeClass alloc] initWithParentBridge:self];
diff --git a/React/Base/RCTBridgeDelegate.h b/React/Base/RCTBridgeDelegate.h
index fb048769ead2c9..f70a024188bad1 100644
--- a/React/Base/RCTBridgeDelegate.h
+++ b/React/Base/RCTBridgeDelegate.h
@@ -41,10 +41,10 @@
- (NSArray> *)extraModulesForBridge:(RCTBridge *)bridge;
/**
- * The location of bundle path, this should be a `file://` url
+ * The location of embedded bundle path, this should be a `file://` url
* pointing to a path inside the bundle resources, e.g. `file://..//main.jsbundle`.
*/
-- (NSURL *)bundledSourceURLForBridge:(RCTBridge *)bridge;
+- (NSURL *)embeddedBundleURLForBridge:(RCTBridge *)bridge;
/**
* Configure whether the JSCExecutor created should use the system JSC API or
diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm
index 88eb814aceb334..871bc46071c255 100644
--- a/React/CxxBridge/RCTCxxBridge.mm
+++ b/React/CxxBridge/RCTCxxBridge.mm
@@ -176,8 +176,8 @@ @implementation RCTCxxBridge
}
@synthesize bridgeDescription = _bridgeDescription;
+@synthesize embeddedBundleURL = _embeddedBundleURL;
@synthesize loading = _loading;
-@synthesize bundledSourceURL = _bundledSourceURL;
@synthesize performanceLogger = _performanceLogger;
@synthesize valid = _valid;
@@ -208,8 +208,8 @@ - (instancetype)initWithParentBridge:(RCTBridge *)bridge
launchOptions:bridge.launchOptions])) {
_parentBridge = bridge;
_performanceLogger = [bridge performanceLogger];
- if ([bridge.delegate respondsToSelector:@selector(bundledSourceURLForBridge:)]) {
- _bundledSourceURL = [bridge.delegate bundledSourceURLForBridge:bridge];
+ if ([bridge.delegate respondsToSelector:@selector(embeddedBundleURLForBridge:)]) {
+ _embeddedBundleURL = [bridge.delegate embeddedBundleURLForBridge:bridge];
}
registerPerformanceLoggerHooks(_performanceLogger);
diff --git a/React/Modules/RCTSourceCode.m b/React/Modules/RCTSourceCode.m
index aab1692010f96b..a7c274a006fd86 100644
--- a/React/Modules/RCTSourceCode.m
+++ b/React/Modules/RCTSourceCode.m
@@ -26,7 +26,7 @@ + (BOOL)requiresMainQueueSetup
{
return @{
@"scriptURL": self.bridge.bundleURL.absoluteString ?: @"",
- @"bundledScriptURL": self.bridge.bundledSourceURL.absoluteString ?: @""
+ @"embeddedBundleURL": self.bridge.embeddedBundleURL.absoluteString ?: @""
};
}
From e11d496e9d907abb5bf58a8300c5a8f85aa03bbb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?H=C3=A9ctor=20Ramos?=
Date: Thu, 9 Nov 2017 09:47:50 -0800
Subject: [PATCH 06/50] Additional markdown adjustments
Summary:
Follow up to 9ec95673909beac7798f589e0e9821b4225f8fa9
Closes https://github.com/facebook/react-native/pull/16759
Differential Revision: D6285219
Pulled By: hramos
fbshipit-source-id: 7012d257a5a6cff06cb2d94203a9379e4b7e3c4e
---
.circleci/config.yml | 19 +-
docs/accessibilityinfo.md | 10 +-
docs/actionsheetios.md | 6 +-
docs/activityindicator.md | 2 +-
docs/alert.md | 2 +-
docs/alertios.md | 26 +-
docs/android-building-from-source.md | 1 +
docs/androiduiperformance.md | 8 +
docs/animated.md | 30 +-
docs/appregistry.md | 20 +-
docs/appstate.md | 43 +-
docs/asyncstorage.md | 103 ++--
docs/backandroid.md | 8 +-
docs/backhandler.md | 18 +-
docs/building-for-apple-tv.md | 1 +
docs/cameraroll.md | 15 +-
docs/checkbox.md | 2 +-
docs/clipboard.md | 14 +-
docs/communication-android.md | 1 +
docs/communication-ios.md | 1 +
docs/custom-webview-android.md | 3 +-
docs/custom-webview-ios.md | 1 +
docs/datepickerandroid.md | 6 +-
docs/datepickerios.md | 2 +-
docs/dimensions.md | 29 +-
docs/drawerlayoutandroid.md | 2 +-
docs/flatlist.md | 542 +++++++++++++++---
docs/geolocation.md | 12 +-
docs/headless-js-android.md | 2 +-
...styleproptypes.md => image-style-props.md} | 43 +-
docs/image.md | 97 +---
docs/imageeditor.md | 21 +-
docs/imagepickerios.md | 8 +-
docs/imagestore.md | 8 +-
docs/integration-with-existing-apps.md | 2 +-
docs/interactionmanager.md | 21 +-
docs/keyboard.md | 8 +-
docs/keyboardavoidingview.md | 4 +-
docs/layout-props.md | 2 +-
docs/layoutanimation.md | 6 +-
docs/linking-libraries-ios.md | 1 +
docs/linking.md | 16 +-
docs/maskedviewios.md | 4 +-
docs/modal.md | 2 +-
docs/native-components-android.md | 1 +
docs/native-components-ios.md | 1 +
docs/native-modules-android.md | 1 +
docs/native-modules-ios.md | 1 +
docs/nativemethodsmixing.md | 8 +
docs/navigatorios.md | 130 +++--
docs/netinfo.md | 82 ++-
docs/panresponder.md | 58 +-
docs/permissionsandroid.md | 87 +--
docs/picker-item.md | 57 ++
docs/picker-style-props.md | 32 ++
docs/picker.md | 55 +-
docs/pickerios.md | 7 +-
docs/pixelratio.md | 46 +-
docs/progressbarandroid.md | 16 +-
docs/progressviewios.md | 2 +-
docs/pushnotificationios.md | 77 ++-
docs/refreshcontrol.md | 2 +-
docs/runningondeviceandroid.md | 8 +
docs/runningondeviceios.md | 8 +
docs/scrollview.md | 39 +-
docs/sectionlist.md | 376 ++++++++++--
docs/segmentedcontrolios.md | 2 +-
docs/settings.md | 8 +-
docs/shadow-props.md | 2 +-
docs/share.md | 18 +-
docs/slider.md | 14 +-
docs/snapshotviewios.md | 3 +-
docs/statusbar.md | 46 +-
docs/statusbarios.md | 10 +-
docs/stylesheet.md | 93 ++-
docs/switch.md | 10 +-
docs/systrace.md | 27 +-
docs/tabbarios-item.md | 11 +-
docs/tabbarios.md | 14 +-
...tstyleproptypes.md => text-style-props.md} | 46 +-
docs/text.md | 1 +
docs/textinput.md | 2 +-
docs/timepickerandroid.md | 6 +-
docs/toastandroid.md | 15 +-
docs/toolbarandroid.md | 2 +-
docs/touchablehighlight.md | 2 +-
docs/touchablenativefeedback.md | 26 +-
docs/touchablewithoutfeedback.md | 10 +-
docs/vibration.md | 14 +-
docs/vibrationios.md | 16 +-
docs/{viewproptypes.md => view-props.md} | 70 +--
...wstyleproptypes.md => view-style-props.md} | 62 +-
docs/view.md | 19 +-
docs/viewpagerandroid.md | 19 +-
docs/virtualizedlist.md | 427 ++++++++++++--
docs/webview.md | 32 +-
96 files changed, 2202 insertions(+), 1091 deletions(-)
create mode 100644 docs/androiduiperformance.md
rename docs/{imagestyleproptypes.md => image-style-props.md} (61%)
create mode 100644 docs/nativemethodsmixing.md
create mode 100644 docs/picker-item.md
create mode 100644 docs/picker-style-props.md
create mode 100644 docs/runningondeviceandroid.md
create mode 100644 docs/runningondeviceios.md
rename docs/{textstyleproptypes.md => text-style-props.md} (67%)
rename docs/{viewproptypes.md => view-props.md} (86%)
rename docs/{viewstyleproptypes.md => view-style-props.md} (58%)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 7ee106ab67709b..32902f12fad5e6 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -239,17 +239,22 @@ jobs:
command: |
cd website
npm install --no-package-lock --no-spin --no-progress
+# The CIRCLE_PROJECT_USERNAME and CIRCLE_PR_USERNAME checks below
+# ensure deploys only happen on projects owned by "facebook",
+# never on a forked PR build.
- run:
name: Build and Deploy Static Website
command: |
- if [[ $CIRCLE_PROJECT_USERNAME == "facebook" && -z $CI_PULL_REQUEST && -z $CIRCLE_PR_USERNAME ]]; then
+ if [[ $CIRCLE_PROJECT_USERNAME == "facebook" && -z $CIRCLE_PR_USERNAME ]]; then
git config --global user.email "reactjs-bot@users.noreply.github.com"
git config --global user.name "Website Deployment Script"
echo "machine github.com login reactjs-bot password $GITHUB_TOKEN" > ~/.netrc
echo "Deploying website..."
cd website && GIT_USER=reactjs-bot npm run gh-pages
+ elif [[ -n $CIRCLE_PR_USERNAME ]]; then
+ echo "Skipping website deploy, this is a forked PR build."
else
- echo "Skipping deploy."
+ echo "Skipping website deploy."
fi
# Build JavaScript bundle for Android tests
@@ -438,10 +443,12 @@ jobs:
- checkout
- restore-cache: *restore-cache-analysis
- run: *install-node-dependencies
+# The CIRCLE_PR_NUMBER checks below ensure
+# code analysis only runs on forked PR builds.
- run:
name: Install Dependencies
command: |
- if [ -n "$CIRCLE_PULL_REQUEST" ]; then
+ if [ -n "$CIRCLE_PR_NUMBER" ]; then
npm install github@0.2.4
cd danger
npm install --no-package-lock --no-spin --no-progress
@@ -453,17 +460,17 @@ jobs:
- run:
name: Analyze Pull Request
command: |
- if [ -n "$CIRCLE_PULL_REQUEST" ]; then
+ if [ -n "$CIRCLE_PR_NUMBER" ]; then
cd danger && DANGER_GITHUB_API_TOKEN="e622517d9f1136ea8900""07c6373666312cdfaa69" npm run danger
else
echo "Skipping pull request analysis."
fi
when: always
-# Run eslint
+# Run eslint
- run:
name: Analyze Code
command: |
- if [ -n "$CIRCLE_PULL_REQUEST" ]; then
+ if [ -n "$CIRCLE_PR_NUMBER" && -n "$CIRCLE_PROJECT_USERNAME" && -n "$CIRCLE_PROJECT_REPONAME" ]; then
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
else
echo "Skipping code analysis."
diff --git a/docs/accessibilityinfo.md b/docs/accessibilityinfo.md
index d85927eafc8040..d1d7625c21867f 100644
--- a/docs/accessibilityinfo.md
+++ b/docs/accessibilityinfo.md
@@ -78,7 +78,7 @@ class ScreenReaderStatusExample extends React.Component {
### `fetch()`
```javascript
-static fetch()
+AccessibilityInfo.fetch()
```
@@ -94,7 +94,7 @@ and `false` otherwise.
### `addEventListener()`
```javascript
-static addEventListener(eventName, handler)
+AccessibilityInfo.addEventListener(eventName, handler)
```
@@ -117,7 +117,7 @@ Add an event handler. Supported events:
### `setAccessibilityFocus()`
```javascript
-static setAccessibilityFocus(reactTag)
+AccessibilityInfo.setAccessibilityFocus(reactTag)
```
@@ -131,7 +131,7 @@ iOS-Only. Set accessibility focus to a react component.
### `announceForAccessibility()`
```javascript
-static announceForAccessibility(announcement)
+AccessibilityInfo.announceForAccessibility(announcement)
```
@@ -145,7 +145,7 @@ iOS-Only. Post a string to be announced by the screen reader.
### `removeEventListener()`
```javascript
-static removeEventListener(eventName, handler)
+AccessibilityInfo.removeEventListener(eventName, handler)
```
diff --git a/docs/actionsheetios.md b/docs/actionsheetios.md
index 2d998d3f167c95..0f97351edd9331 100644
--- a/docs/actionsheetios.md
+++ b/docs/actionsheetios.md
@@ -8,7 +8,7 @@ next: alert
previous: accessibilityinfo
---
-
+Display action sheets and share sheets on iOS.
### Methods
@@ -27,7 +27,7 @@ previous: accessibilityinfo
### `showActionSheetWithOptions()`
```javascript
-static showActionSheetWithOptions(options, callback)
+ActionSheetIOS.showActionSheetWithOptions(options, callback)
```
@@ -65,7 +65,7 @@ ActionSheetIOS.showActionSheetWithOptions({
### `showShareActionSheetWithOptions()`
```javascript
-static showShareActionSheetWithOptions(options, failureCallback, successCallback)
+ActionSheetIOS.showShareActionSheetWithOptions(options, failureCallback, successCallback)
```
diff --git a/docs/activityindicator.md b/docs/activityindicator.md
index f00406d2911b00..4b6f22d9046ca6 100644
--- a/docs/activityindicator.md
+++ b/docs/activityindicator.md
@@ -51,7 +51,7 @@ AppRegistry.registerComponent('App', () => App)
### Props
-* [ViewPropTypes props...](docs/viewproptypes.html#props)
+- [View props...](docs/view-props.html)
- [`animating`](docs/activityindicator.html#animating)
- [`color`](docs/activityindicator.html#color)
- [`size`](docs/activityindicator.html#size)
diff --git a/docs/alert.md b/docs/alert.md
index 87f67237581991..63de1f42d8bc9a 100644
--- a/docs/alert.md
+++ b/docs/alert.md
@@ -72,7 +72,7 @@ Alert.alert(
### `alert()`
```javascript
-static alert(title, message?, buttons?, options?, type?)
+Alert.alert(title, message?, buttons?, options?, type?)
```
diff --git a/docs/alertios.md b/docs/alertios.md
index 7079e67bfde6ca..ffd4e51e08cd48 100644
--- a/docs/alertios.md
+++ b/docs/alertios.md
@@ -56,7 +56,7 @@ cross-platform support if you don't need to create iOS-only prompts.
### `alert()`
```javascript
-static alert(title: string, [message]: string, [callbackOrButtons]: ?(() => void), ButtonsArray, [type]: AlertType): [object Object]
+AlertIOS.alert(title: string, [message]: string, [callbackOrButtons]: ?(() => void), ButtonsArray, [type]: AlertType): [object Object]
```
Create and display a popup alert.
@@ -65,10 +65,10 @@ Create and display a popup alert.
| Name | Type | Required | Description |
| - | - | - | - |
-| title | string | No | The dialog's title. Passing null or '' will hide the title. |
-| message | string | Yes | An optional message that appears below the dialog's title. |
-| callbackOrButtons | ?(() => void),[ButtonsArray](docs/alertios.html#buttonsarray) | Yes | This optional argument should be either a single-argument function or an array of buttons. If passed a function, it will be called when the user taps 'OK'. If passed an array of button configurations, each button should include a `text` key, as well as optional `onPress` and `style` keys. `style` should be one of 'default', 'cancel' or 'destructive'. |
-| type | [AlertType](docs/alertios.html#alerttype) | Yes | Deprecated, do not use. |
+| title | string | Yes | The dialog's title. Passing null or '' will hide the title. |
+| message | string | No | An optional message that appears below the dialog's title. |
+| callbackOrButtons | ?(() => void),[ButtonsArray](docs/alertios.html#buttonsarray) | No | This optional argument should be either a single-argument function or an array of buttons. If passed a function, it will be called when the user taps 'OK'. If passed an array of button configurations, each button should include a `text` key, as well as optional `onPress` and `style` keys. `style` should be one of 'default', 'cancel' or 'destructive'. |
+| type | [AlertType](docs/alertios.html#alerttype) | No | Deprecated, do not use. |
@@ -93,7 +93,7 @@ AlertIOS.alert(
### `prompt()`
```javascript
-static prompt(title: string, [message]: string, [callbackOrButtons]: ?((text: string) => void), ButtonsArray, [type]: AlertType, [defaultValue]: string, [keyboardType]: string): [object Object]
+AlertIOS.prompt(title: string, [message]: string, [callbackOrButtons]: ?((text: string) => void), ButtonsArray, [type]: AlertType, [defaultValue]: string, [keyboardType]: string): [object Object]
```
Create and display a prompt to enter some text.
@@ -102,12 +102,12 @@ Create and display a prompt to enter some text.
| Name | Type | Required | Description |
| - | - | - | - |
-| title | string | No | The dialog's title. |
-| message | string | Yes | An optional message that appears above the text input. |
-| callbackOrButtons | ?((text: string) => void),[ButtonsArray](docs/alertios.html#buttonsarray) | Yes | This optional argument should be either a single-argument function or an array of buttons. If passed a function, it will be called with the prompt's value when the user taps 'OK'. If passed an array of button configurations, each button should include a `text` key, as well as optional `onPress` and `style` keys (see example). `style` should be one of 'default', 'cancel' or 'destructive'. |
-| type | [AlertType](docs/alertios.html#alerttype) | Yes | This configures the text input. One of 'plain-text', 'secure-text' or 'login-password'. |
-| defaultValue | string | Yes | The default text in text input. |
-| keyboardType | string | Yes | The keyboard type of first text field(if exists). One of 'default', 'email-address', 'numeric', 'phone-pad', 'ascii-capable', 'numbers-and-punctuation', 'url', 'number-pad', 'name-phone-pad', 'decimal-pad', 'twitter' or 'web-search'. |
+| title | string | Yes | The dialog's title. |
+| message | string | No | An optional message that appears above the text input. |
+| callbackOrButtons | ?((text: string) => void),[ButtonsArray](docs/alertios.html#buttonsarray) | No | This optional argument should be either a single-argument function or an array of buttons. If passed a function, it will be called with the prompt's value when the user taps 'OK'. If passed an array of button configurations, each button should include a `text` key, as well as optional `onPress` and `style` keys (see example). `style` should be one of 'default', 'cancel' or 'destructive'. |
+| type | [AlertType](docs/alertios.html#alerttype) | No | This configures the text input. One of 'plain-text', 'secure-text' or 'login-password'. |
+| defaultValue | string | No | The default text in text input. |
+| keyboardType | string | No | The keyboard type of first text field(if exists). One of 'default', 'email-address', 'numeric', 'phone-pad', 'ascii-capable', 'numbers-and-punctuation', 'url', 'number-pad', 'name-phone-pad', 'decimal-pad', 'twitter' or 'web-search'. |
@@ -191,7 +191,7 @@ An Alert button style
### ButtonsArray
-Array or buttons
+Array of buttons
| Type |
| - |
diff --git a/docs/android-building-from-source.md b/docs/android-building-from-source.md
index 62b7d37d9f5f31..d88c46cdef5340 100644
--- a/docs/android-building-from-source.md
+++ b/docs/android-building-from-source.md
@@ -4,6 +4,7 @@ title: Building React Native from source
layout: docs
category: Guides (Android)
permalink: docs/android-building-from-source.html
+banner: ejected
next: communication-android
previous: android-ui-performance
---
diff --git a/docs/androiduiperformance.md b/docs/androiduiperformance.md
new file mode 100644
index 00000000000000..d24ffd24b83c21
--- /dev/null
+++ b/docs/androiduiperformance.md
@@ -0,0 +1,8 @@
+---
+id: android-ui-performance
+title: Profiling Android UI Performance
+layout: redirect
+permalink: docs/android-ui-performance.html
+destinationUrl: performance.html
+---
+Redirecting...
\ No newline at end of file
diff --git a/docs/animated.md b/docs/animated.md
index aa6b6ae915d17a..a18f4cb2857317 100644
--- a/docs/animated.md
+++ b/docs/animated.md
@@ -533,25 +533,51 @@ static unforkEvent(event, listener)
## Properties
+### Value
+Standard value class for driving animations. Typically initialized with `new Animated.Value(0);`
----
+See also `AnimatedValue.js`.
+| Type |
+| - |
+| AnimatedValue |
---
+### ValueXY
+2D value class for driving 2D animations, such as pan gestures.
----
+See also `AnimatedValueXY.js`.
+
+| Type |
+| - |
+| AnimatedValueXY |
---
+### Interpolation
+
+Exported to use the Interpolation type in flow
+
+See also `AnimatedInterpolation.js`.
+| Type |
+| - |
+| AnimatedInterpolation |
---
+### Node
+
+Exported for ease of type checking. All animated values derive from this class.
+
+| Type |
+| - |
+| AnimatedNode |
diff --git a/docs/appregistry.md b/docs/appregistry.md
index 83d119244601d6..81b5129441f520 100644
--- a/docs/appregistry.md
+++ b/docs/appregistry.md
@@ -199,12 +199,13 @@ static registerHeadlessTask(taskKey, task)
Register a headless task. A headless task is a bit of code that runs without a UI.
-@param taskKey the key associated with this task
-@param task a promise returning function that takes some data passed from the native side as
- the only argument; when the promise is resolved or rejected the native side is
- notified of this event and it may decide to destroy the JS context.
+**Parameters:**
+| Name | Type | Required | Description |
+| - | - | - | - |
+| taskKey | string | No | The key associated with this task. |
+| task | function | No | A promise returning function that takes some data passed from the native side as the only argument; when the promise is resolved or rejected the native side is notified of this event and it may decide to destroy the JS context. |
---
@@ -215,12 +216,15 @@ Register a headless task. A headless task is a bit of code that runs without a U
static startHeadlessTask(taskId, taskKey, data)
```
-
Only called from native code. Starts a headless task.
-@param taskId the native id for this task instance to keep track of its execution
-@param taskKey the key for the task to start
-@param data the data to pass to the task
+**Parameters:**
+
+| Name | Type | Required | Description |
+| - | - | - | - |
+| taskId | number | No | The native id for this task instance to keep track of its execution |
+| taskKey | string | No | The key for the task to start |
+| data | any | No | The data to pass to the task |
diff --git a/docs/appstate.md b/docs/appstate.md
index ee208e3d0f9906..efe0e1274d33a2 100644
--- a/docs/appstate.md
+++ b/docs/appstate.md
@@ -16,23 +16,18 @@ handling push notifications.
### App States
- - `active` - The app is running in the foreground
- - `background` - The app is running in the background. The user is either
- in another app or on the home screen
- - `inactive` - This is a state that occurs when transitioning between
- foreground & background, and during periods of inactivity such as
- entering the Multitasking view or in the event of an incoming call
+- `active` - The app is running in the foreground
+- `background` - The app is running in the background. The user is either
+ in another app or on the home screen
+- `inactive` - This is a state that occurs when transitioning between foreground & background, and during periods of inactivity such as entering the Multitasking view or in the event of an incoming call
-For more information, see
-[Apple's documentation](https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html)
+For more information, see [Apple's documentation](https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html)
### Basic Usage
-To see the current state, you can check `AppState.currentState`, which
-will be kept up-to-date. However, `currentState` will be null at launch
-while `AppState` retrieves it over the bridge.
+To see the current state, you can check `AppState.currentState`, which will be kept up-to-date. However, `currentState` will be null at launch while `AppState` retrieves it over the bridge.
-```
+```javascript
import React, {Component} from 'react'
import {AppState, Text} from 'react-native'
@@ -66,14 +61,11 @@ class AppStateExample extends Component {
}
```
-This example will only ever appear to say "Current state is: active" because
-the app is only visible to the user when in the `active` state, and the null
-state will happen only momentarily.
+This example will only ever appear to say "Current state is: active" because the app is only visible to the user when in the `active` state, and the null state will happen only momentarily.
### Methods
-- [`=`](docs/appstate.html#)
- [`addEventListener`](docs/appstate.html#addeventlistener)
- [`removeEventListener`](docs/appstate.html#removeeventlistener)
@@ -86,16 +78,6 @@ state will happen only momentarily.
## Methods
-### `=()`
-
-```javascript
-=(;, ()
-```
-
-
-
----
-
### `addEventListener()`
```javascript
@@ -106,15 +88,6 @@ addEventListener(type, handler)
Add a handler to AppState changes by listening to the `change` event type
and providing the handler
-TODO: now that AppState is a subclass of NativeEventEmitter, we could deprecate
-`addEventListener` and `removeEventListener` and just use `addListener` and
-`listener.remove()` directly. That will be a breaking change though, as both
-the method and event names are different (addListener events are currently
-required to be globally unique).
-
-
-
-
---
### `removeEventListener()`
diff --git a/docs/asyncstorage.md b/docs/asyncstorage.md
index 2a88f2d47d0b1e..01c18672285dc4 100644
--- a/docs/asyncstorage.md
+++ b/docs/asyncstorage.md
@@ -7,24 +7,17 @@ permalink: docs/asyncstorage.html
next: backandroid
previous: appstate
---
-`AsyncStorage` is a simple, unencrypted, asynchronous, persistent, key-value storage
-system that is global to the app. It should be used instead of LocalStorage.
+`AsyncStorage` is a simple, unencrypted, asynchronous, persistent, key-value storage system that is global to the app. It should be used instead of LocalStorage.
-It is recommended that you use an abstraction on top of `AsyncStorage`
-instead of `AsyncStorage` directly for anything more than light usage since
-it operates globally.
+It is recommended that you use an abstraction on top of `AsyncStorage` instead of `AsyncStorage` directly for anything more than light usage since it operates globally.
-On iOS, `AsyncStorage` is backed by native code that stores small values in a
-serialized dictionary and larger values in separate files. On Android,
-`AsyncStorage` will use either [RocksDB](http://rocksdb.org/) or SQLite
-based on what is available.
+On iOS, `AsyncStorage` is backed by native code that stores small values in a serialized dictionary and larger values in separate files. On Android, `AsyncStorage` will use either [RocksDB](http://rocksdb.org/) or SQLite based on what is available.
-The `AsyncStorage` JavaScript code is a simple facade that provides a clear
-JavaScript API, real `Error` objects, and simple non-multi functions. Each
-method in the API returns a `Promise` object.
+The `AsyncStorage` JavaScript code is a simple facade that provides a clear JavaScript API, real `Error` objects, and simple non-multi functions. Each method in the API returns a `Promise` object.
Persisting data:
-```
+
+```javascript
try {
await AsyncStorage.setItem('@MySuperStore:key', 'I like to save it.');
} catch (error) {
@@ -33,7 +26,8 @@ try {
```
Fetching data:
-```
+
+```javascript
try {
const value = await AsyncStorage.getItem('@MySuperStore:key');
if (value !== null){
@@ -53,6 +47,11 @@ try {
- [`mergeItem`](docs/asyncstorage.html#mergeitem)
- [`clear`](docs/asyncstorage.html#clear)
- [`getAllKeys`](docs/asyncstorage.html#getallkeys)
+
+The following batched functions are useful for executing a lot of operations at once, allowing for native optimizations and provide the convenience of a single callback after all operations are complete.
+
+These functions return arrays of errors, potentially one for every key. For key-specific errors, the Error object will have a key property to indicate which key caused the error.
+
- [`flushGetRequests`](docs/asyncstorage.html#flushgetrequests)
- [`multiGet`](docs/asyncstorage.html#multiget)
- [`multiSet`](docs/asyncstorage.html#multiset)
@@ -81,8 +80,8 @@ Returns a `Promise` object.
| Name | Type | Required | Description |
| - | - | - | - |
-| key | string | No | Key of the item to fetch. |
-| callback | ?(error: ?Error, result: ?string) => void | Yes | Function that will be called with a result if found or any error. |
+| key | string | Yes | Key of the item to fetch. |
+| callback | ?(error: ?Error, result: ?string) => void | No | Function that will be called with a result if found or any error. |
@@ -95,16 +94,17 @@ Returns a `Promise` object.
static setItem(key: string, value: string, [callback]: ?(error: ?Error) => void)
```
-Sets the value for a `key` and invokes a callback upon completion.
+Sets the value for a `key` and invokes a callback upon completion.
+
Returns a `Promise` object.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
-| key | string | No | Key of the item to set. |
-| value | string | No | Value to set for the `key`. |
-| callback | ?(error: ?Error) => void | Yes | Function that will be called with any error. |
+| key | string | Yes | Key of the item to set. |
+| value | string | Yes | Value to set for the `key`. |
+| callback | ?(error: ?Error) => void | No | Function that will be called with any error. |
@@ -124,8 +124,8 @@ Returns a `Promise` object.
| Name | Type | Required | Description |
| - | - | - | - |
-| key | string | No | Key of the item to remove. |
-| callback | ?(error: ?Error) => void | Yes | Function that will be called with any error. |
+| key | string | Yes | Key of the item to remove. |
+| callback | ?(error: ?Error) => void | No | Function that will be called with any error. |
@@ -138,35 +138,32 @@ Returns a `Promise` object.
static mergeItem(key: string, value: string, [callback]: ?(error: ?Error) => void)
```
-Merges an existing `key` value with an input value, assuming both values
-are stringified JSON. Returns a `Promise` object.
+Merges an existing `key` value with an input value, assuming both values are stringified JSON. Returns a `Promise` object.
-**NOTE:** This is not supported by all native implementations.
+> Note:
+> This is not supported by all native implementations.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
-| key | string | No | Key of the item to modify. |
-| value | string | No | New value to merge for the `key`. |
-| callback | ?(error: ?Error) => void | Yes | Function that will be called with any error. |
-
-
+| key | string | Yes | Key of the item to modify. |
+| value | string | Yes | New value to merge for the `key`. |
+| callback | ?(error: ?Error) => void | No | Function that will be called with any error. |
Example:
```javascript
-
let UID123_object = {
- name: 'Chris',
- age: 30,
- traits: {hair: 'brown', eyes: 'brown'},
+ name: 'Chris',
+ age: 30,
+ traits: {hair: 'brown', eyes: 'brown'},
};
// You only need to define what will be added or updated
let UID123_delta = {
- age: 31,
- traits: {eyes: 'blue', shoe_size: 10}
+ age: 31,
+ traits: {eyes: 'blue', shoe_size: 10}
};
AsyncStorage.setItem('UID123', JSON.stringify(UID123_object), () => {
@@ -182,8 +179,6 @@ AsyncStorage.setItem('UID123', JSON.stringify(UID123_object), () => {
// {'shoe_size':10,'hair':'brown','eyes':'blue'}}
```
-
-
---
### `clear()`
@@ -192,15 +187,13 @@ AsyncStorage.setItem('UID123', JSON.stringify(UID123_object), () => {
static clear([callback]: ?(error: ?Error) => void)
```
-Erases *all* `AsyncStorage` for all clients, libraries, etc. You probably
-don't want to call this; use `removeItem` or `multiRemove` to clear only
-your app's keys. Returns a `Promise` object.
+Erases *all* `AsyncStorage` for all clients, libraries, etc. You probably don't want to call this; use `removeItem` or `multiRemove` to clear only your app's keys. Returns a `Promise` object.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
-| callback | ?(error: ?Error) => void | Yes | Function that will be called with any error. |
+| callback | ?(error: ?Error) => void | No | Function that will be called with any error. |
@@ -220,7 +213,7 @@ Returns a `Promise` object.
| Name | Type | Required | Description |
| - | - | - | - |
-| callback | ?(error: ?Error, keys: ?Array) => void | Yes | Function that will be called the keys found and any error. |
+| callback | ?(error: ?Error, keys: ?Array) => void | No | Function that will be called the keys found and any error. |
@@ -235,8 +228,6 @@ static flushGetRequests(): [object Object]
Flushes any pending requests using a single batch call to get the data.
-
-
---
### `multiGet()`
@@ -245,9 +236,7 @@ Flushes any pending requests using a single batch call to get the data.
static multiGet(keys: Array, [callback]: ?(errors: ?Array, result: ?Array>) => void)
```
-This allows you to batch the fetching of items given an array of `key`
-inputs. Your callback will be invoked with an array of corresponding
-key-value pairs found:
+This allows you to batch the fetching of items given an array of `key` inputs. Your callback will be invoked with an array of corresponding key-value pairs found:
```
multiGet(['k1', 'k2'], cb) -> cb([['k1', 'val1'], ['k2', 'val2']])
@@ -259,10 +248,8 @@ The method returns a `Promise` object.
| Name | Type | Required | Description |
| - | - | - | - |
-| keys | Array | No | Array of key for the items to get. |
-| callback | ?(errors: ?Array, result: ?Array>) => void | Yes | Function that will be called with a key-value array of the results, plus an array of any key-specific errors found. |
-
-
+| keys | Array | Yes | Array of key for the items to get. |
+| callback | ?(errors: ?Array, result: ?Array>) => void | No | Function that will be called with a key-value array of the results, plus an array of any key-specific errors found. |
Example:
@@ -302,8 +289,8 @@ The method returns a `Promise` object.
| Name | Type | Required | Description |
| - | - | - | - |
-| keyValuePairs | Array> | No | Array of key-value array for the items to set. |
-| callback | ?(errors: ?Array) => void | Yes | Function that will be called with an array of any key-specific errors found. |
+| keyValuePairs | Array> | Yes | Array of key-value array for the items to set. |
+| callback | ?(errors: ?Array) => void | No | Function that will be called with an array of any key-specific errors found. |
@@ -323,8 +310,8 @@ a `Promise` object.
| Name | Type | Required | Description |
| - | - | - | - |
-| keys | Array | No | Array of key for the items to delete. |
-| callback | ?(errors: ?Array) => void | Yes | Function that will be called an array of any key-specific errors found. |
+| keys | Array | Yes | Array of key for the items to delete. |
+| callback | ?(errors: ?Array) => void | No | Function that will be called an array of any key-specific errors found. |
@@ -360,8 +347,8 @@ keys. This assumes that the values are stringified JSON. Returns a
| Name | Type | Required | Description |
| - | - | - | - |
-| keyValuePairs | Array> | No | Array of key-value array for the items to merge. |
-| callback | ?(errors: ?Array) => void | Yes | Function that will be called with an array of any key-specific errors found. |
+| keyValuePairs | Array> | Yes | Array of key-value array for the items to merge. |
+| callback | ?(errors: ?Array) => void | No | Function that will be called with an array of any key-specific errors found. |
diff --git a/docs/backandroid.md b/docs/backandroid.md
index 0ee553c67bc16c..0dd040cd3525c7 100644
--- a/docs/backandroid.md
+++ b/docs/backandroid.md
@@ -8,7 +8,7 @@ next: backhandler
previous: asyncstorage
---
-Deprecated. Use BackHandler instead.
+**Deprecated.** Use [BackHandler](docs/backhandler.html) instead.
### Methods
@@ -29,7 +29,7 @@ Deprecated. Use BackHandler instead.
### `exitApp()`
```javascript
-static exitApp()
+BackAndroid.exitApp()
```
@@ -39,7 +39,7 @@ static exitApp()
### `addEventListener()`
```javascript
-static addEventListener(eventName, handler)
+BackAndroid.addEventListener(eventName, handler)
```
@@ -49,7 +49,7 @@ static addEventListener(eventName, handler)
### `removeEventListener()`
```javascript
-static removeEventListener(eventName, handler)
+BackAndroid.removeEventListener(eventName, handler)
```
diff --git a/docs/backhandler.md b/docs/backhandler.md
index 890a9325ca6ca6..57f2a8b9e46805 100644
--- a/docs/backhandler.md
+++ b/docs/backhandler.md
@@ -10,17 +10,13 @@ previous: backhandler
Detect hardware button presses for back navigation.
-Android: Detect hardware back button presses, and programmatically invoke the default back button
-functionality to exit the app if there are no listeners or if none of the listeners return true.
+**Android:** Detect hardware back button presses, and programmatically invoke the default back button functionality to exit the app if there are no listeners or if none of the listeners return true.
-tvOS: Detect presses of the menu button on the TV remote. (Still to be implemented:
-programmatically disable menu button handling
-functionality to exit the app if there are no listeners or if none of the listeners return true.)
+**tvOS:** Detect presses of the menu button on the TV remote. Still to be implemented: programmatically disable menu button handling functionality to exit the app if there are no listeners or if none of the listeners return true.
-iOS: Not applicable.
+**iOS:** Not applicable.
-The event subscriptions are called in reverse order (i.e. last registered subscription first),
-and if one subscription returns true then subscriptions registered earlier will not be called.
+The event subscriptions are called in reverse order (i.e. last registered subscription first), and if one subscription returns true then subscriptions registered earlier will not be called.
Example:
@@ -56,7 +52,7 @@ BackHandler.addEventListener('hardwareBackPress', function() {
### `exitApp()`
```javascript
-static exitApp()
+BackHandler.exitApp()
```
@@ -66,7 +62,7 @@ static exitApp()
### `addEventListener()`
```javascript
-static addEventListener(eventName, handler)
+BackHandler.addEventListener(eventName, handler)
```
@@ -76,7 +72,7 @@ static addEventListener(eventName, handler)
### `removeEventListener()`
```javascript
-static removeEventListener(eventName, handler)
+BackHandler.removeEventListener(eventName, handler)
```
diff --git a/docs/building-for-apple-tv.md b/docs/building-for-apple-tv.md
index 1692353f2ca1eb..0dc6128cb97c9b 100644
--- a/docs/building-for-apple-tv.md
+++ b/docs/building-for-apple-tv.md
@@ -4,6 +4,7 @@ title: Building For Apple TV
layout: docs
category: Guides (iOS)
permalink: docs/building-for-apple-tv.html
+banner: ejected
next: app-extensions
previous: communication-ios
---
diff --git a/docs/cameraroll.md b/docs/cameraroll.md
index 15741c80375f8c..127aecd7cbeb6f 100644
--- a/docs/cameraroll.md
+++ b/docs/cameraroll.md
@@ -21,7 +21,6 @@ app will use this data. This key will appear as `Privacy - Photo Library Usage D
### Methods
-- [`=`](docs/cameraroll.html#)
- [`saveToCameraRoll`](docs/cameraroll.html#savetocameraroll)
- [`getPhotos`](docs/cameraroll.html#getphotos)
@@ -34,20 +33,10 @@ app will use this data. This key will appear as `Privacy - Photo Library Usage D
## Methods
-### `=()`
-
-```javascript
-=(;, AssetTypeOptions, static, (, :)
-```
-
-
-
----
-
### `saveToCameraRoll()`
```javascript
-static saveToCameraRoll(tag, type?)
+CameraRoll.saveToCameraRoll(tag, type?)
```
@@ -72,7 +61,7 @@ Returns a Promise which will resolve with the new URI.
### `getPhotos()`
```javascript
-static getPhotos(params)
+CameraRoll.getPhotos(params)
```
diff --git a/docs/checkbox.md b/docs/checkbox.md
index 100d67434b6bb4..679b5df885a98c 100644
--- a/docs/checkbox.md
+++ b/docs/checkbox.md
@@ -19,7 +19,7 @@ the supplied `value` prop instead of the expected result of any user actions.
### Props
-* [ViewPropTypes props...](docs/viewproptypes.html#props)
+- [View props...](docs/view-props.html)
- [`disabled`](docs/checkbox.html#disabled)
- [`onChange`](docs/checkbox.html#onchange)
- [`onValueChange`](docs/checkbox.html#onvaluechange)
diff --git a/docs/clipboard.md b/docs/clipboard.md
index 5d6dd7af1e1ec4..47a9e3488359dd 100644
--- a/docs/clipboard.md
+++ b/docs/clipboard.md
@@ -28,7 +28,7 @@ previous: cameraroll
### `getString()`
```javascript
-static getString()
+Clipboard.getString()
```
@@ -47,17 +47,23 @@ async _getContent() {
### `setString()`
```javascript
-static setString(content)
+Clipboard.setString(content)
```
-Set content of string type. You can use following code to set clipboard content
+Set content of string type. You can use following code to set clipboard content:
+
```javascript
_setContent() {
Clipboard.setString('hello world');
}
```
-@param the content to be stored in the clipboard.
+
+**Parameters:**
+
+| Name | Type | Required | Description |
+| - | - | - | - |
+| content | string | yes | The content to be stored in the clipboard. |
diff --git a/docs/communication-android.md b/docs/communication-android.md
index 675d2eba940a1b..133be47408c753 100644
--- a/docs/communication-android.md
+++ b/docs/communication-android.md
@@ -4,6 +4,7 @@ title: Communication between native and React Native
layout: docs
category: Guides (Android)
permalink: docs/communication-android.html
+banner: ejected
next: contributing
previous: android-building-from-source
---
diff --git a/docs/communication-ios.md b/docs/communication-ios.md
index 16851169e1b752..7be7fb4a914ea4 100644
--- a/docs/communication-ios.md
+++ b/docs/communication-ios.md
@@ -4,6 +4,7 @@ title: Communication between native and React Native
layout: docs
category: Guides (iOS)
permalink: docs/communication-ios.html
+banner: ejected
next: building-for-apple-tv
previous: linking-libraries-ios
---
diff --git a/docs/custom-webview-android.md b/docs/custom-webview-android.md
index f3dcf7e76f24ce..73dbfaf5621052 100644
--- a/docs/custom-webview-android.md
+++ b/docs/custom-webview-android.md
@@ -4,6 +4,7 @@ title: Custom WebView
layout: docs
category: Guides (Android)
permalink: docs/custom-webview-android.html
+banner: ejected
next: headless-js-android
previous: native-components-android
---
@@ -213,7 +214,7 @@ For events, the event handler must always be set to a function. This means it is
If you are unsure how something should be implemented from the JS side, look at [WebView.android.js](https://github.com/facebook/react-native/blob/master/Libraries/Components/WebView/WebView.android.js) in the React Native source.
-```js
+```javascript
export default class CustomWebView extends Component {
static propTypes = {
...WebView.propTypes,
diff --git a/docs/custom-webview-ios.md b/docs/custom-webview-ios.md
index 8f4de9fdff6b69..8c2d51f80c88fe 100644
--- a/docs/custom-webview-ios.md
+++ b/docs/custom-webview-ios.md
@@ -4,6 +4,7 @@ title: Custom WebView
layout: docs
category: Guides (iOS)
permalink: docs/custom-webview-ios.html
+banner: ejected
next: linking-libraries-ios
previous: native-components-ios
---
diff --git a/docs/datepickerandroid.md b/docs/datepickerandroid.md
index 7b16e10c166ee1..55f2819f6d239f 100644
--- a/docs/datepickerandroid.md
+++ b/docs/datepickerandroid.md
@@ -46,7 +46,7 @@ try {
### `open()`
```javascript
-static open(options)
+DatePickerAndroid.open(options)
```
@@ -78,7 +78,7 @@ when using the `minDate` and `maxDate` options.
### `dateSetAction()`
```javascript
-static dateSetAction()
+DatePickerAndroid.dateSetAction()
```
@@ -92,7 +92,7 @@ A date has been selected.
### `dismissedAction()`
```javascript
-static dismissedAction()
+DatePickerAndroid.dismissedAction()
```
diff --git a/docs/datepickerios.md b/docs/datepickerios.md
index 60c6dc70bc8972..43795a3321d6f6 100644
--- a/docs/datepickerios.md
+++ b/docs/datepickerios.md
@@ -15,7 +15,7 @@ source of truth.
### Props
-* [ViewPropTypes props...](docs/viewproptypes.html#props)
+- [View props...](docs/view-props.html)
- [`date`](docs/datepickerios.html#date)
- [`onDateChange`](docs/datepickerios.html#ondatechange)
- [`maximumDate`](docs/datepickerios.html#maximumdate)
diff --git a/docs/dimensions.md b/docs/dimensions.md
index 4e57aaf445598c..65db7d95ecf4ca 100644
--- a/docs/dimensions.md
+++ b/docs/dimensions.md
@@ -29,14 +29,18 @@ previous: datepickerandroid
### `set()`
```javascript
-static set(dims)
+Dimensions.set(dims)
```
This should only be called from native code by sending the
didUpdateDimensions event.
-@param {object} dims Simple string-keyed object of dimensions to set
+**Parameters:**
+
+| Name | Type | Required | Description |
+| - | - | - | - |
+| dims | object | Yes | Simple string-keyed object of dimensions to set |
@@ -46,23 +50,24 @@ didUpdateDimensions event.
### `get()`
```javascript
-static get(dim)
+Dimensions.get(dim)
```
Initial dimensions are set before `runApplication` is called so they should
be available before any other require's are run, but may be updated later.
-Note: Although dimensions are available immediately, they may change (e.g
-due to device rotation) so any rendering logic or styles that depend on
-these constants should try to call this function on every render, rather
-than caching the value (for example, using inline styles rather than
-setting a value in a `StyleSheet`).
+> Note:
+> Although dimensions are available immediately, they may change (e.g due to device rotation) so any rendering logic or styles that depend on these constants should try to call this function on every render, rather than caching the value (for example, using inline styles rather than setting a value in a `StyleSheet`).
Example: `var {height, width} = Dimensions.get('window');`
-@param {string} dim Name of dimension as defined when calling `set`.
-@returns {Object?} Value for the dimension.
+**Parameters:**
+
+| Name | Type | Required | Description |
+| - | - | - | - |
+| dim | string | Yes | Name of dimension as defined when calling `set`. |
+
@@ -72,7 +77,7 @@ Example: `var {height, width} = Dimensions.get('window');`
### `addEventListener()`
```javascript
-static addEventListener(type, handler)
+Dimensions.addEventListener(type, handler)
```
@@ -91,7 +96,7 @@ Add an event handler. Supported events:
### `removeEventListener()`
```javascript
-static removeEventListener(type, handler)
+Dimensions.removeEventListener(type, handler)
```
diff --git a/docs/drawerlayoutandroid.md b/docs/drawerlayoutandroid.md
index b9ae9809148ce6..0a2a393f0635f3 100644
--- a/docs/drawerlayoutandroid.md
+++ b/docs/drawerlayoutandroid.md
@@ -39,7 +39,7 @@ render: function() {
### Props
-* [ViewPropTypes props...](docs/viewproptypes.html#props)
+- [View props...](docs/view-props.html)
- [`renderNavigationView`](docs/drawerlayoutandroid.html#rendernavigationview)
- [`onDrawerClose`](docs/drawerlayoutandroid.html#ondrawerclose)
- [`drawerPosition`](docs/drawerlayoutandroid.html#drawerposition)
diff --git a/docs/flatlist.md b/docs/flatlist.md
index 6ab1309ccd0039..617363de60e20a 100644
--- a/docs/flatlist.md
+++ b/docs/flatlist.md
@@ -23,10 +23,12 @@ If you need section support, use [``](docs/sectionlist.html).
Minimal Example:
+```javascript
{item.key}}
/>
+```
More complex, multi-select example demonstrating `PureComponent` usage for perf optimization and avoiding bugs.
@@ -39,87 +41,101 @@ More complex, multi-select example demonstrating `PureComponent` usage for perf
not show any changes.
- `keyExtractor` tells the list to use the `id`s for the react keys instead of the default `key` property.
+```javascript
+class MyListItem extends React.PureComponent {
+ _onPress = () => {
+ this.props.onPressItem(this.props.id);
+ };
+
+ render() {
+ const textColor = this.props.selected ? "red" : "black";
+ return (
+
+
+
+ {this.props.title}
+
+
+
+ );
+ }
+}
+
+class MultiSelectList extends React.PureComponent {
+ state = {selected: (new Map(): Map)};
+
+ _keyExtractor = (item, index) => item.id;
+
+ _onPressItem = (id: string) => {
+ // updater functions are preferred for transactional updates
+ this.setState((state) => {
+ // copy the map rather than modifying state.
+ const selected = new Map(state.selected);
+ selected.set(id, !selected.get(id)); // toggle
+ return {selected};
+ });
+ };
+
+ _renderItem = ({item}) => (
+
+ );
+
+ render() {
+ return (
+
+ );
+ }
+}
+```
- class MyListItem extends React.PureComponent {
- _onPress = () => {
- this.props.onPressItem(this.props.id);
- };
-
- render() {
- const textColor = this.props.selected ? "red" : "black";
- return (
-
-
-
- {this.props.title}
-
-
-
- );
- }
- }
-
- class MultiSelectList extends React.PureComponent {
- state = {selected: (new Map(): Map)};
-
- _keyExtractor = (item, index) => item.id;
-
- _onPressItem = (id: string) => {
- // updater functions are preferred for transactional updates
- this.setState((state) => {
- // copy the map rather than modifying state.
- const selected = new Map(state.selected);
- selected.set(id, !selected.get(id)); // toggle
- return {selected};
- });
- };
-
- _renderItem = ({item}) => (
-
- );
-
- render() {
- return (
-
- );
- }
- }
-
-This is a convenience wrapper around [``](docs/virtualizedlist.html),
-and thus inherits its props (as well as those of `ScrollView`) that aren't explicitly listed
-here, along with the following caveats:
-
-- Internal state is not preserved when content scrolls out of the render window. Make sure all
- your data is captured in the item data or external stores like Flux, Redux, or Relay.
-- This is a `PureComponent` which means that it will not re-render if `props` remain shallow-
- equal. Make sure that everything your `renderItem` function depends on is passed as a prop
- (e.g. `extraData`) that is not `===` after updates, otherwise your UI may not update on
- changes. This includes the `data` prop and parent component state.
-- In order to constrain memory and enable smooth scrolling, content is rendered asynchronously
- offscreen. This means it's possible to scroll faster than the fill rate ands momentarily see
- blank content. This is a tradeoff that can be adjusted to suit the needs of each application,
- and we are working on improving it behind the scenes.
-- By default, the list looks for a `key` prop on each item and uses that for the React key.
- Alternatively, you can provide a custom `keyExtractor` prop.
-
-Also inherits [ScrollView Props](docs/scrollview.html#props), unless it is nested in another FlatList of same orientation.
-
-### Props
+This is a convenience wrapper around [`VirtualizedList`](docs/virtualizedlist.html), and thus inherits its props (as well as those of `ScrollView`) that aren't explicitly listed here, along with the following caveats:
-- [`numColumns`](docs/flatlist.html#numcolumns)
+- Internal state is not preserved when content scrolls out of the render window. Make sure all your data is captured in the item data or external stores like Flux, Redux, or Relay.
+- This is a `PureComponent` which means that it will not re-render if `props` remain shallow- equal. Make sure that everything your `renderItem` function depends on is passed as a prop (e.g. `extraData`) that is not `===` after updates, otherwise your UI may not update on changes. This includes the `data` prop and parent component state.
+- In order to constrain memory and enable smooth scrolling, content is rendered asynchronously offscreen. This means it's possible to scroll faster than the fill rate ands momentarily see blank content. This is a tradeoff that can be adjusted to suit the needs of each application, and we are working on improving it behind the scenes.
+- By default, the list looks for a `key` prop on each item and uses that for the React key. Alternatively, you can provide a custom `keyExtractor` prop.
+Also inherits [ScrollView props](docs/scrollview.html#props), unless it is nested in another `FlatList` of same orientation.
+### Props
+- [`ScrollView` props...](docs/scrollview.html#props)
+- [`VirtualizedList` props...](docs/virtualizedlist.html#props)
+- [`renderItem`](docs/flatlist.html#renderitem)
+- [`data`](docs/flatlist.html#data)
+- [`ItemSeparatorComponent`](docs/flatlist.html#itemseparatorcomponent)
+- [`ListEmptyComponent`](docs/flatlist.html#listemptycomponent)
+- [`ListFooterComponent`](docs/flatlist.html#listgootercomponent)
+- [`ListHeaderComponent`](docs/flatlist.html#listheadercomponent)
+- [`columnwrapperstyle`](docs/flatlist.html#columnwrapperstyle)
+- [`extraData`](docs/flatlist.html#extradata)
+- [`getItemLayout`](docs/flatlist.html#getitemlayout)
+- [`horizontal`](docs/flatlist.html#horizontal)
+- [`initialNumToRender`](docs/flatlist.html#initialnumtorender)
+- [`initialScrollIndex`](docs/flatlist.html#initialscrollindex)
+- [`inverted`](docs/flatlist.html#inverted)
+- [`keyExtractor`](docs/flatlist.html#keyextractor)
+- [`numColumns`](docs/flatlist.html#numcolumns)
+- [`onEndReached`](docs/flatlist.html#onendreached)
+- [`onEndReachedThreshold`](docs/flatlist.html#onendreachedthreshold)
+- [`onRefresh`](docs/flatlist.html#onrefresh)
+- [`onViewableItemsChanged`](docs/flatlist.html#onviewableitemschanged)
+- [`progressViewOffset`](docs/flatlist.html#progressviewoffset)
+- [`legacyImplementation`](docs/flatlist.html#legacyimplementation)
+- [`refreshing`](docs/flatlist.html#refreshing)
+- [`removeClippedSubviews`](docs/flatlist.html#removeclippedsubviews)
+- [`viewabilityConfig`](docs/flatlist.html#viewabilityconfig)
+- [`viewabilityConfigCallbackPairs`](docs/flatlist.html#viewabilityconfigcallbackpairs)
### Methods
@@ -145,18 +161,390 @@ Also inherits [ScrollView Props](docs/scrollview.html#props), unless it is neste
## Props
+### `renderItem`
+
+```javascript
+renderItem({ item: object, index: number, separators: { highlight: function, unhighlight: function, updateProps: function(select: string, newProps: object) } }): [element]
+```
+
+Takes an item from `data` and renders it into the list.
+
+Provides additional metadata like `index` if you need it, as well as a more generic `separators.updateProps` function which let's you set whatever props you want to change the rendering of either the leading separator or trailing separator in case the more common `highlight` and `unhighlight` (which set the `highlighted: boolean` prop) are insufficient for your use case.
+
+| Type | Required |
+| - | - |
+| function | Yes |
+
+
+Example usage:
+
+```javascript
+ (
+
+ )}
+ data={[{title: 'Title Text', key: 'item1'}]}
+ renderItem={({item, separators}) => (
+ this._onPress(item)}
+ onShowUnderlay={separators.highlight}
+ onHideUnderlay={separators.unhighlight}>
+
+ {item.title}
+
+
+ )}
+ />
+```
+
+
+---
+
+
+### `data`
+
+For simplicity, data is just a plain array. If you want to use something else, like an immutable list, use the underlying [`VirtualizedList`](docs/virtualizedlist.html) directly.
+
+| Type | Required |
+| - | - |
+| array | Yes |
+
+
+
+---
+
+
+### `ItemSeparatorComponent`
+
+Rendered in between each item, but not at the top or bottom. By default, `highlighted` and `leadingItem` props are provided. `renderItem` provides `separators.highlight`/`unhighlight` which will update the `highlighted` prop, but you can also add custom props with `separators.updateProps`.
+
+| Type | Required |
+| - | - |
+| component | No |
+
+
+
+---
+
+
+### `ListEmptyComponent`
+
+Rendered when the list is empty. Can be a React Component Class, a render function, or a rendered element.
+
+| Type | Required |
+| - | - |
+| component, function, element | No |
+
+
+
+---
+
+
+### `ListFooterComponent`
+
+Rendered at the bottom of all the items. Can be a React Component Class, a render function, or a rendered element.
+
+| Type | Required |
+| - | - |
+| component, function, element | No |
+
+
+
+---
+
+
+### `ListHeaderComponent`
+
+Rendered at the top of all the items. Can be a React Component Class, a render function, or a rendered element.
+
+| Type | Required |
+| - | - |
+| component, function, element | No |
+
+
+
+---
+
+
+### `columnWrapperStyle`
+
+Optional custom style for multi-item rows generated when `numColumns > 1`.
+
+| Type | Required |
+| - | - |
+| style object | No |
+
+
+
+---
+
+
+### `extraData`
+
+A marker property for telling the list to re-render (since it implements `PureComponent`). If any of your `renderItem`, Header, Footer, etc. functions depend on anything outside of the `data` prop, stick it here and treat it immutably.
+
+| Type | Required |
+| - | - |
+| any | No |
+
+
+
+
+---
+
+
+### `getItemLayout`
+
+```javascript
+(data, index) => {length: number, offset: number, index: number}
+```
+
+`getItemLayout` is an optional optimization that let us skip measurement of dynamic content if you know the height of items a priori. `getItemLayout` is the most efficient, and is easy to use if you have fixed height items, for example:
+
+```javascript
+ getItemLayout={(data, index) => (
+ {length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index}
+ )}
+```
+
+Adding `getItemLayout` can be a great performance boost for lists of several hundred items. Remember to include separator length (height or width) in your offset calculation if you specify `ItemSeparatorComponent`.
+
+| Type | Required |
+| - | - |
+| function | No |
+
+
+
+---
+
+
+### `horizontal`
+
+If true, renders items next to each other horizontally instead of stacked vertically.
+
+| Type | Required |
+| - | - |
+| boolean | No |
+
+
+
+---
+
+
+### `initialNumToRender`
+
+How many items to render in the initial batch. This should be enough to fill the screen but not much more. Note these items will never be unmounted as part of the windowed rendering in order to improve perceived performance of scroll-to-top actions.
+
+| Type | Required |
+| - | - |
+| number | No |
+
+
+
+---
+
+
+### `initialScrollIndex`
+
+Instead of starting at the top with the first item, start at `initialScrollIndex`. This disables the "scroll to top" optimization that keeps the first `initialNumToRender` items always rendered and immediately renders the items starting at this initial index. Requires `getItemLayout` to be implemented.
+
+| Type | Required |
+| - | - |
+| number | No |
+
+
+
+---
+
+
+### `inverted`
+
+Reverses the direction of scroll. Uses scale transforms of `-1`.
+
+| Type | Required |
+| - | - |
+| boolean | No |
+
+
+
+---
+
+
+### `keyExtractor`
+
+```javascript
+(item: object, index: number) => string
+```
+
+Used to extract a unique key for a given item at the specified index. Key is used for caching and as the react key to track item re-ordering. The default extractor checks `item.key`, then falls back to using the index, like React does.
+
+| Type | Required |
+| - | - |
+| function | No |
+
+
+
+
+---
+
+
### `numColumns`
+Multiple columns can only be rendered with `horizontal={false}` and will zig-zag like a `flexWrap` layout. Items should all be the same height - masonry layouts are not supported.
+| Type | Required |
+| - | - |
+| number | No |
+
+
+
+
+---
+
+
+### `onEndReached`
+
+```javascript
+(info: {distanceFromEnd: number}) => void
+```
+
+Called once when the scroll position gets within `onEndReachedThreshold` of the rendered content.
+
+| Type | Required |
+| - | - |
+| function | No |
+
+
+
+---
+
+
+### `onEndReachedThreshold`
+
+ How far from the end (in units of visible length of the list) the bottom edge of the list must be from the end of the content to trigger the `onEndReached` callback. Thus a value of 0.5 will trigger `onEndReached` when the end of the content is within half the visible length of the list.
| Type | Required |
| - | - |
-| | No |
+| number | No |
+---
+### `onRefresh`
+
+```javascript
+() => void
+```
+
+If provided, a standard RefreshControl will be added for "Pull to Refresh" functionality. Make sure to also set the `refreshing` prop correctly.
+
+| Type | Required |
+| - | - |
+| function | No |
+
+
+
+---
+
+
+### `onViewableItemsChanged`
+
+```javascript
+(info: {
+ viewableItems: array,
+ changed: array,
+ }) => void
+```
+
+Called when the viewability of rows changes, as defined by the `viewabilityConfig` prop.
+
+| Type | Required |
+| - | - |
+| function | No |
+
+
+
+---
+
+
+### `progressViewOffset`
+
+Set this when offset is needed for the loading indicator to show correctly.
+
+| Type | Required | Platform |
+| - | - | - |
+| number | No | Android |
+
+
+
+---
+
+
+### `legacyImplementation`
+
+May not have full feature parity and is meant for debugging and performance comparison.
+
+| Type | Required |
+| - | - |
+| boolean | No |
+
+
+
+---
+
+
+### `refreshing`
+
+Set this true while waiting for new data from a refresh.
+
+| Type | Required |
+| - | - |
+| boolean | No |
+
+
+
+---
+
+
+### `removeClippedSubviews`
+
+This may improve scroll performance for large lists.
+
+> Note:
+> May have bugs (missing content) in some circumstances - use at your own risk.
+
+| Type | Required |
+| - | - |
+| boolean | No |
+
+
+
+---
+
+
+### `viewabilityConfig`
+
+See `ViewabilityHelper.js` for flow type and further documentation.
+
+| Type | Required |
+| - | - |
+| ViewabilityConfig | No |
+
+
+
+---
+
+
+### `viewabilityConfigCallbackPairs`
+
+List of `ViewabilityConfig`/`onViewableItemsChanged` pairs. A specific `onViewableItemsChanged` will be called when its corresponding `ViewabilityConfig`'s conditions are met. See `ViewabilityHelper.js` for flow type and further documentation.
+
+| Type | Required |
+| - | - |
+| array of ViewabilityConfigCallbackPair | No |
+
## Methods
diff --git a/docs/geolocation.md b/docs/geolocation.md
index 09bb454687d037..ab83e0d54637f9 100644
--- a/docs/geolocation.md
+++ b/docs/geolocation.md
@@ -74,7 +74,7 @@ was created from a mock provider.
### `setRNConfiguration()`
```javascript
-static setRNConfiguration(config)
+Geolocation.setRNConfiguration(config)
```
@@ -96,7 +96,7 @@ before using Geolocation APIs.
### `requestAuthorization()`
```javascript
-static requestAuthorization()
+Geolocation.requestAuthorization()
```
@@ -113,7 +113,7 @@ authorization.
### `getCurrentPosition()`
```javascript
-static getCurrentPosition(geo_success, geo_error?, geo_options?)
+Geolocation.getCurrentPosition(geo_success, geo_error?, geo_options?)
```
@@ -130,7 +130,7 @@ or it will request an update which might take a while.
### `watchPosition()`
```javascript
-static watchPosition(success, error?, options?)
+Geolocation.watchPosition(success, error?, options?)
```
@@ -145,7 +145,7 @@ options: timeout (ms), maximumAge (ms), enableHighAccuracy (bool), distanceFilte
### `clearWatch()`
```javascript
-static clearWatch(watchID)
+Geolocation.clearWatch(watchID)
```
@@ -155,7 +155,7 @@ static clearWatch(watchID)
### `stopObserving()`
```javascript
-static stopObserving()
+Geolocation.stopObserving()
```
diff --git a/docs/headless-js-android.md b/docs/headless-js-android.md
index 99aa333484ba6e..4f51a232fceab4 100644
--- a/docs/headless-js-android.md
+++ b/docs/headless-js-android.md
@@ -89,7 +89,7 @@ Following lines shows part of Android manifest file for registering broadcast re
```
-Broadcast receiver then handles intent that was broadcasted in onReceive function. This is a great place to check whether your app is on foreground or not. If app is not on foreground we can prepare our intent to be started, with no information or additional information bundled using putExta (keep in mind bundle can handle only parcelable values). In the end service is started and wakelock is acquired.
+Broadcast receiver then handles intent that was broadcasted in onReceive function. This is a great place to check whether your app is on foreground or not. If app is not on foreground we can prepare our intent to be started, with no information or additional information bundled using `putExtra` (keep in mind bundle can handle only parcelable values). In the end service is started and wakelock is acquired.
```java
public class NetworkChangeReceiver extends BroadcastReceiver {
diff --git a/docs/imagestyleproptypes.md b/docs/image-style-props.md
similarity index 61%
rename from docs/imagestyleproptypes.md
rename to docs/image-style-props.md
index eaac32b31f1ee9..1aff1d5091cc14 100644
--- a/docs/imagestyleproptypes.md
+++ b/docs/image-style-props.md
@@ -1,31 +1,34 @@
---
-id: imagestyleproptypes
-title: ImageStylePropTypes
+id: image-style-props
+title: Image Style Props
layout: docs
category: APIs
-permalink: docs/imagestyleproptypes.html
+permalink: docs/image-style-props.html
next: null
-previous: textstyleproptypes
+previous: text-style-props
---
-### Props
-
-- [`borderTopRightRadius`](docs/imagestyleproptypes.html#bordertoprightradius)
-- [`backfaceVisibility`](docs/imagestyleproptypes.html#backfacevisibility)
-- [`borderBottomLeftRadius`](docs/imagestyleproptypes.html#borderbottomleftradius)
-- [`borderBottomRightRadius`](docs/imagestyleproptypes.html#borderbottomrightradius)
-- [`borderColor`](docs/imagestyleproptypes.html#bordercolor)
-- [`borderRadius`](docs/imagestyleproptypes.html#borderradius)
-- [`borderTopLeftRadius`](docs/imagestyleproptypes.html#bordertopleftradius)
-- [`backgroundColor`](docs/imagestyleproptypes.html#backgroundcolor)
-- [`borderWidth`](docs/imagestyleproptypes.html#borderwidth)
-- [`opacity`](docs/imagestyleproptypes.html#opacity)
-- [`overflow`](docs/imagestyleproptypes.html#overflow)
-- [`resizeMode`](docs/imagestyleproptypes.html#resizemode)
-- [`tintColor`](docs/imagestyleproptypes.html#tintcolor)
-- [`overlayColor`](docs/imagestyleproptypes.html#overlaycolor)
+[Image](docs/image.html) style props.
+### Props
+- [Layout Props...](docs/layout-props.html#props)
+- [Shadow Props...](docs/shadow-props.html#props)
+- [Transforms...](docs/transforms.html#props)
+- [`borderTopRightRadius`](docs/image-style-props.html#bordertoprightradius)
+- [`backfaceVisibility`](docs/image-style-props.html#backfacevisibility)
+- [`borderBottomLeftRadius`](docs/image-style-props.html#borderbottomleftradius)
+- [`borderBottomRightRadius`](docs/image-style-props.html#borderbottomrightradius)
+- [`borderColor`](docs/image-style-props.html#bordercolor)
+- [`borderRadius`](docs/image-style-props.html#borderradius)
+- [`borderTopLeftRadius`](docs/image-style-props.html#bordertopleftradius)
+- [`backgroundColor`](docs/image-style-props.html#backgroundcolor)
+- [`borderWidth`](docs/image-style-props.html#borderwidth)
+- [`opacity`](docs/image-style-props.html#opacity)
+- [`overflow`](docs/image-style-props.html#overflow)
+- [`resizeMode`](docs/image-style-props.html#resizemode)
+- [`tintColor`](docs/image-style-props.html#tintcolor)
+- [`overlayColor`](docs/image-style-props.html#overlaycolor)
diff --git a/docs/image.md b/docs/image.md
index 804262a25622d0..d60304e4f03c98 100644
--- a/docs/image.md
+++ b/docs/image.md
@@ -109,7 +109,6 @@ Also, if you use GIF with ProGuard, you will need to add this rule in `proguard-
### Props
-- [`style`](docs/image.html#style)
- [`blurRadius`](docs/image.html#blurradius)
- [`onLayout`](docs/image.html#onlayout)
- [`onLoad`](docs/image.html#onload)
@@ -126,6 +125,7 @@ Also, if you use GIF with ProGuard, you will need to add this rule in `proguard-
- [`defaultSource`](docs/image.html#defaultsource)
- [`onPartialLoad`](docs/image.html#onpartialload)
- [`onProgress`](docs/image.html#onprogress)
+- [`style`](docs/image.html#style)
@@ -144,73 +144,6 @@ Also, if you use GIF with ProGuard, you will need to add this rule in `proguard-
## Props
-### `style`
-
-> `ImageResizeMode` is an `Enum` for different image resizing modes, set via the
-> `resizeMode` style property on `Image` components. The values are `contain`, `cover`,
-> `stretch`, `center`, `repeat`.
-
-| Type | Required |
-| - | - |
-| style | No |
-
-
- - [Layout Props...](docs/layout-props.html#props)
-
- - [Shadow Props...](docs/shadow-props.html#props)
-
- - [Transforms...](docs/transforms.html#props)
-
- - **`borderTopRightRadius`**: number
-
- - **`backfaceVisibility`**: enum('visible', 'hidden')
-
- - **`borderBottomLeftRadius`**: number
-
- - **`borderBottomRightRadius`**: number
-
- - **`borderColor`**: [color](docs/colors.html)
-
- - **`borderRadius`**: number
-
- - **`borderTopLeftRadius`**: number
-
- - **`backgroundColor`**: [color](docs/colors.html)
-
- - **`borderWidth`**: number
-
- - **`opacity`**: number
-
- - **`overflow`**: enum('visible', 'hidden')
-
- - **`resizeMode`**: Object.keys(ImageResizeMode)
-
- - **`tintColor`**: [color](docs/colors.html)
-
- Changes the color of all the non-transparent pixels to the tintColor.
-
- - **`overlayColor`**: string (_Android_)
-
- When the image has rounded corners, specifying an overlayColor will
- cause the remaining space in the corners to be filled with a solid color.
- This is useful in cases which are not supported by the Android
- implementation of rounded corners:
- - Certain resize modes, such as 'contain'
- - Animated GIFs
-
- A typical way to use this prop is with images displayed on a solid
- background and setting the `overlayColor` to the same color
- as the background.
-
- For details of how this works under the hood, see
- http://frescolib.org/docs/rounded-corners-and-circles.html
-
-
-
-
-
----
-
### `blurRadius`
blurRadius: the blur radius of the blur filter added to the image
@@ -483,27 +416,25 @@ Invoked on download progress with `{nativeEvent: {loaded, total}}`.
| function | No | iOS |
+---
+### `style`
-
+| Type | Required |
+| - | - |
+| [style](docs/imagestyleproptypes.html) | No |
## Methods
### `getSize()`
```javascript
-static getSize(uri: string, success: function, [failure]: function):
+static getSize(uri: string, success: function, [failure]: function): void
```
-Retrieve the width and height (in pixels) of an image prior to displaying it.
-This method can fail if the image cannot be found, or fails to download.
+Retrieve the width and height (in pixels) of an image prior to displaying it. This method can fail if the image cannot be found, or fails to download.
-In order to retrieve the image dimensions, the image may first need to be
-loaded or downloaded, after which it will be cached. This means that in
-principle you could use this method to preload images, however it is not
-optimized for that purpose, and may in future be implemented in a way that
-does not fully load/download the image data. A proper, supported way to
-preload images will be provided as a separate API.
+In order to retrieve the image dimensions, the image may first need to be loaded or downloaded, after which it will be cached. This means that in principle you could use this method to preload images, however it is not optimized for that purpose, and may in future be implemented in a way that does not fully load/download the image data. A proper, supported way to preload images will be provided as a separate API.
Does not work for static image resources.
@@ -511,9 +442,9 @@ Does not work for static image resources.
| Name | Type | Required | Description |
| - | - | - | - |
-| uri | string | No | The location of the image. |
-| success | function | No | The function that will be called if the image was successfully found and widthand height retrieved. |
-| failure | function | Yes | The function that will be called if there was an error, such as failing toto retrieve the image. |
+| uri | string | Yes | The location of the image. |
+| success | function | Yes | The function that will be called if the image was successfully found and widthand height retrieved. |
+| failure | function | No | The function that will be called if there was an error, such as failing toto retrieve the image. |
@@ -523,7 +454,7 @@ Does not work for static image resources.
### `prefetch()`
```javascript
-static prefetch(url: string):
+Image.prefetch(url: string):
```
Prefetches a remote image for later use by downloading it to the disk
@@ -533,7 +464,7 @@ cache
| Name | Type | Required | Description |
| - | - | - | - |
-| url | string | No | The remote location of the image. |
+| url | string | Yes | The remote location of the image. |
diff --git a/docs/imageeditor.md b/docs/imageeditor.md
index d0ec17a2fbe079..6495335866c3b8 100644
--- a/docs/imageeditor.md
+++ b/docs/imageeditor.md
@@ -26,19 +26,20 @@ previous: geolocation
### `cropImage()`
```javascript
-static cropImage(uri, cropData, success, failure)
+ImageEditor.cropImage(uri, cropData, success, failure)
```
+Crop the image specified by the URI param. If URI points to a remote image, it will be downloaded automatically. If the image cannot be loaded/downloaded, the failure callback will be called.
-Crop the image specified by the URI param. If URI points to a remote
-image, it will be downloaded automatically. If the image cannot be
-loaded/downloaded, the failure callback will be called.
-
-If the cropping process is successful, the resultant cropped image
-will be stored in the ImageStore, and the URI returned in the success
-callback will point to the image in the store. Remember to delete the
-cropped image from the ImageStore when you are done with it.
-
+If the cropping process is successful, the resultant cropped image will be stored in the ImageStore, and the URI returned in the success callback will point to the image in the store. Remember to delete the cropped image from the ImageStore when you are done with it.
+**Crop Data Options:**
+The following options can be used with the `cropData` parameter:
+| Name | Type | Required | Description |
+| - | - | - | - |
+| offset | `{ x: number, y: number}` | Yes | The top-left corner of the cropped image, specified in the original image's coordinate space. |
+| size | `{ width: number, height: number }` | Yes | The size (dimensions) of the cropped image, specified in the original image's coordinate space. |
+| displaySize | `{ width: number, height: number }` | No | Size to scale the cropped image to. |
+| resizeMode | `enum( contain: string, cover: string, stretch: string }` | No | The resizing mode to use when scaling the image. If the `displaySize` param is not specified, this has no effect. |
diff --git a/docs/imagepickerios.md b/docs/imagepickerios.md
index 238f2437239a7e..52670059309f6b 100644
--- a/docs/imagepickerios.md
+++ b/docs/imagepickerios.md
@@ -29,7 +29,7 @@ previous: imageeditor
### `canRecordVideos()`
```javascript
-static canRecordVideos(callback)
+ImagePickerIOS.canRecordVideos(callback)
```
@@ -39,7 +39,7 @@ static canRecordVideos(callback)
### `canUseCamera()`
```javascript
-static canUseCamera(callback)
+ImagePickerIOS.canUseCamera(callback)
```
@@ -49,7 +49,7 @@ static canUseCamera(callback)
### `openCameraDialog()`
```javascript
-static openCameraDialog(config, successCallback, cancelCallback)
+ImagePickerIOS.openCameraDialog(config, successCallback, cancelCallback)
```
@@ -59,7 +59,7 @@ static openCameraDialog(config, successCallback, cancelCallback)
### `openSelectDialog()`
```javascript
-static openSelectDialog(config, successCallback, cancelCallback)
+ImagePickerIOS.openSelectDialog(config, successCallback, cancelCallback)
```
diff --git a/docs/imagestore.md b/docs/imagestore.md
index 910ec25907fd42..a0210206c9a09e 100644
--- a/docs/imagestore.md
+++ b/docs/imagestore.md
@@ -29,7 +29,7 @@ previous: imagepickerios
### `hasImageForTag()`
```javascript
-static hasImageForTag(uri, callback)
+ImageStore.hasImageForTag(uri, callback)
```
@@ -44,7 +44,7 @@ Check if the ImageStore contains image data for the specified URI.
### `removeImageForTag()`
```javascript
-static removeImageForTag(uri)
+ImageStore.removeImageForTag(uri)
```
@@ -63,7 +63,7 @@ will simply fail silently.
### `addImageFromBase64()`
```javascript
-static addImageFromBase64(base64ImageData, success, failure)
+ImageStore.addImageFromBase64(base64ImageData, success, failure)
```
@@ -85,7 +85,7 @@ than necessary.
### `getBase64ForTag()`
```javascript
-static getBase64ForTag(uri, success, failure)
+ImageStore.getBase64ForTag(uri, success, failure)
```
diff --git a/docs/integration-with-existing-apps.md b/docs/integration-with-existing-apps.md
index 8f708c9b79116a..3aebba0fceb78e 100644
--- a/docs/integration-with-existing-apps.md
+++ b/docs/integration-with-existing-apps.md
@@ -361,7 +361,7 @@ const styles = StyleSheet.create({
});
// Module name
-AppRegistry.registerComponent('MyReactNativeApp', () => RNHighScores);
+AppRegistry.registerComponent('RNHighScores', () => RNHighScores);
```
> `RNHighScores` is the name of your module that will be used when you add a view to React Native from within your iOS application.
diff --git a/docs/interactionmanager.md b/docs/interactionmanager.md
index cb034edc4e9372..e76e85a64bfc82 100644
--- a/docs/interactionmanager.md
+++ b/docs/interactionmanager.md
@@ -63,12 +63,12 @@ from executing, making apps more responsive.
- [`createInteractionHandle`](docs/interactionmanager.html#createinteractionhandle)
- [`clearInteractionHandle`](docs/interactionmanager.html#clearinteractionhandle)
- [`setDeadline`](docs/interactionmanager.html#setdeadline)
+- [`addListener`](docs/interactionmanager.html#addlistener)
### Properties
- [`Events`](docs/interactionmanager.html#events)
-- [`addListener`](docs/interactionmanager.html#addlistener)
@@ -82,7 +82,7 @@ from executing, making apps more responsive.
### `runAfterInteractions()`
```javascript
-static runAfterInteractions(task)
+InteractionManager.runAfterInteractions(task)
```
@@ -97,7 +97,7 @@ Schedule a function to run after all interactions have completed. Returns a canc
### `createInteractionHandle()`
```javascript
-static createInteractionHandle()
+InteractionManager.createInteractionHandle()
```
@@ -111,7 +111,7 @@ Notify manager that an interaction has started.
### `clearInteractionHandle()`
```javascript
-static clearInteractionHandle(handle)
+InteractionManager.clearInteractionHandle(handle)
```
@@ -125,7 +125,7 @@ Notify manager that an interaction has completed.
### `setDeadline()`
```javascript
-static setDeadline(deadline)
+InteractionManager.setDeadline(deadline)
```
@@ -133,14 +133,21 @@ A positive number will use setTimeout to schedule any tasks after the
eventLoopRunningTime hits the deadline value, otherwise all tasks will be
executed in one setImmediate batch (default).
+---
+### `addListener()`
+```javascript
+InteractionManager.addListener(EventEmitter)
+```
-## Properties
+## Properties
----
+### `Events`
+- `interactionStart`
+- `interactionComplete`
diff --git a/docs/keyboard.md b/docs/keyboard.md
index 374a7e588d167e..418611d31f6dc6 100644
--- a/docs/keyboard.md
+++ b/docs/keyboard.md
@@ -68,7 +68,7 @@ class Example extends Component {
### `addListener()`
```javascript
-static addListener(eventName, callback)
+Keyboard.addListener(eventName, callback)
```
@@ -102,7 +102,7 @@ since there is no native corresponding event.
### `removeListener()`
```javascript
-static removeListener(eventName, callback)
+Keyboard.removeListener(eventName, callback)
```
@@ -119,7 +119,7 @@ Removes a specific listener.
### `removeAllListeners()`
```javascript
-static removeAllListeners(eventName)
+Keyboard.removeAllListeners(eventName)
```
@@ -135,7 +135,7 @@ Removes all listeners for a specific event type.
### `dismiss()`
```javascript
-static dismiss()
+Keyboard.dismiss()
```
diff --git a/docs/keyboardavoidingview.md b/docs/keyboardavoidingview.md
index b13b3ff9c7f2a6..b5e0fdff23aa7a 100644
--- a/docs/keyboardavoidingview.md
+++ b/docs/keyboardavoidingview.md
@@ -12,7 +12,7 @@ It can automatically adjust either its position or bottom padding based on the p
### Props
-* [ViewPropTypes props...](docs/viewproptypes.html#props)
+- [ViewPropTypes props...](docs/viewproptypes.html#props)
- [`keyboardVerticalOffset`](docs/keyboardavoidingview.html#keyboardverticaloffset)
- [`behavior`](docs/keyboardavoidingview.html#behavior)
- [`contentContainerStyle`](docs/keyboardavoidingview.html#contentcontainerstyle)
@@ -68,7 +68,7 @@ The style of the content container(View) when behavior is 'position'.
| Type | Required |
| - | - |
-| ViewPropTypes.style | No |
+| [ViewPropTypes.style](docs/viewproptypes.html#style) | No |
diff --git a/docs/layout-props.md b/docs/layout-props.md
index 6e5e919c523c62..90d4d39c92443b 100644
--- a/docs/layout-props.md
+++ b/docs/layout-props.md
@@ -4,7 +4,7 @@ title: Layout Props
layout: docs
category: APIs
permalink: docs/layout-props.html
-next: shadow-props
+next: picker-style-props
previous: vibrationios
---
### Props
diff --git a/docs/layoutanimation.md b/docs/layoutanimation.md
index 5e4255938d3da6..31a92f2c6b9244 100644
--- a/docs/layoutanimation.md
+++ b/docs/layoutanimation.md
@@ -46,7 +46,7 @@ Note that in order to get this to work on **Android** you need to set the follow
### `configureNext()`
```javascript
-static configureNext(config, onAnimationDidEnd?)
+LayoutAnimation.configureNext(config, onAnimationDidEnd?)
```
@@ -71,7 +71,7 @@ Only supported on iOS.
### `create()`
```javascript
-static create(duration, type, creationProp)
+LayoutAnimation.create(duration, type, creationProp)
```
@@ -85,7 +85,7 @@ Helper for creating a config for `configureNext`.
### `checkConfig()`
```javascript
-static checkConfig(config, location, name)
+LayoutAnimation.checkConfig(config, location, name)
```
diff --git a/docs/linking-libraries-ios.md b/docs/linking-libraries-ios.md
index 672eadbcfaff10..ad15d09db6e05e 100644
--- a/docs/linking-libraries-ios.md
+++ b/docs/linking-libraries-ios.md
@@ -4,6 +4,7 @@ title: Linking Libraries
layout: docs
category: Guides (iOS)
permalink: docs/linking-libraries-ios.html
+banner: ejected
next: running-on-simulator-ios
previous: custom-webview-ios
---
diff --git a/docs/linking.md b/docs/linking.md
index 6eed2276e6e8ae..a3194bfb2dd3aa 100644
--- a/docs/linking.md
+++ b/docs/linking.md
@@ -206,10 +206,9 @@ The method returns a `Promise` object. If the user confirms the open dialog or t
url automatically opens, the promise is resolved. If the user cancels the open dialog
or there are no registered applications for the url, the promise is rejected.
-NOTE: This method will fail if the system doesn't know how to open the specified URL.
-If you're passing in a non-http(s) URL, it's best to check {@code canOpenURL} first.
+> This method will fail if the system doesn't know how to open the specified URL. If you're passing in a non-http(s) URL, it's best to check {@code canOpenURL} first.
-NOTE: For web URLs, the protocol ("http://", "https://") must be set accordingly!
+> For web URLs, the protocol ("http://", "https://") must be set accordingly!
@@ -225,13 +224,16 @@ canOpenURL(url)
Determine whether or not an installed app can handle a given URL.
-NOTE: For web URLs, the protocol ("http://", "https://") must be set accordingly!
+> For web URLs, the protocol ("http://", "https://") must be set accordingly!
-NOTE: As of iOS 9, your app needs to provide the `LSApplicationQueriesSchemes` key
+> As of iOS 9, your app needs to provide the `LSApplicationQueriesSchemes` key
inside `Info.plist` or canOpenURL will always return false.
-@param URL the URL to open
+**Parameters:**
+| Name | Type | Required | Description |
+| - | - | - | - |
+| url | string | Yes | The URL to open |
@@ -247,7 +249,7 @@ getInitialURL()
If the app launch was triggered by an app link,
it will give the link url, otherwise it will give `null`
-NOTE: To support deep linking on Android, refer http://developer.android.com/training/app-indexing/deep-linking.html#handling-intents
+> To support deep linking on Android, refer http://developer.android.com/training/app-indexing/deep-linking.html#handling-intents
diff --git a/docs/maskedviewios.md b/docs/maskedviewios.md
index 91ca93b1e331f1..0de578a532ef64 100644
--- a/docs/maskedviewios.md
+++ b/docs/maskedviewios.md
@@ -43,7 +43,7 @@ transparent pixels block that content.
### Props
-* [ViewPropTypes props...](docs/viewproptypes.html#props)
+- [View props...](docs/view-props.html)
- [`maskElement`](docs/maskedviewios.html#maskelement)
@@ -59,7 +59,7 @@ transparent pixels block that content.
### `maskElement`
-
+Should be a React element to be rendered and applied as the mask for the child element.
| Type | Required |
| - | - |
diff --git a/docs/modal.md b/docs/modal.md
index ac2255d9b32aa7..673fb545932f04 100644
--- a/docs/modal.md
+++ b/docs/modal.md
@@ -67,7 +67,7 @@ The `onRequestClose` callback is called when the user taps the hardware back but
| Type | Required |
| - | - |
-| (Platform.isTVOS || Platform.OS === 'android') ? PropTypes.func.isRequired : PropTypes.func | No |
+| function | Required on Android and Apple TV |
diff --git a/docs/native-components-android.md b/docs/native-components-android.md
index fdee7e4dcf879a..5d0a96e2fc8087 100644
--- a/docs/native-components-android.md
+++ b/docs/native-components-android.md
@@ -4,6 +4,7 @@ title: Native UI Components
layout: docs
category: Guides (Android)
permalink: docs/native-components-android.html
+banner: ejected
next: custom-webview-android
previous: native-modules-android
---
diff --git a/docs/native-components-ios.md b/docs/native-components-ios.md
index 85ca430ca72b8a..231f78df6f5197 100644
--- a/docs/native-components-ios.md
+++ b/docs/native-components-ios.md
@@ -4,6 +4,7 @@ title: Native UI Components
layout: docs
category: Guides (iOS)
permalink: docs/native-components-ios.html
+banner: ejected
next: custom-webview-ios
previous: native-modules-ios
---
diff --git a/docs/native-modules-android.md b/docs/native-modules-android.md
index 7ff9adacba677e..e4365f187c9f83 100644
--- a/docs/native-modules-android.md
+++ b/docs/native-modules-android.md
@@ -4,6 +4,7 @@ title: Native Modules
layout: docs
category: Guides (Android)
permalink: docs/native-modules-android.html
+banner: ejected
next: native-components-android
previous: app-extensions
---
diff --git a/docs/native-modules-ios.md b/docs/native-modules-ios.md
index fa2f760808ab91..de8fe85fe0336d 100644
--- a/docs/native-modules-ios.md
+++ b/docs/native-modules-ios.md
@@ -4,6 +4,7 @@ title: Native Modules
layout: docs
category: Guides (iOS)
permalink: docs/native-modules-ios.html
+banner: ejected
next: native-components-ios
previous: testing
---
diff --git a/docs/nativemethodsmixing.md b/docs/nativemethodsmixing.md
new file mode 100644
index 00000000000000..59e87a89ccd4a5
--- /dev/null
+++ b/docs/nativemethodsmixing.md
@@ -0,0 +1,8 @@
+---
+id: NativeMethodsMixin
+title: NativeMethodsMixin
+layout: redirect
+permalink: docs/nativemethodsmixin.html
+destinationUrl: direct-manipulation.html#other-native-methods
+---
+Redirecting...
\ No newline at end of file
diff --git a/docs/navigatorios.md b/docs/navigatorios.md
index 342902885fdd7a..893e2ad32b42b5 100644
--- a/docs/navigatorios.md
+++ b/docs/navigatorios.md
@@ -7,21 +7,11 @@ permalink: docs/navigatorios.html
next: picker
previous: modal
---
-`NavigatorIOS` is a wrapper around
-[`UINavigationController`](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UINavigationController_Class/),
-enabling you to implement a navigation stack. It works exactly the same as it
-would on a native app using `UINavigationController`, providing the same
-animations and behavior from UIKit.
-
-As the name implies, it is only available on iOS. Take a look at
-[`React Navigation`](https://reactnavigation.org/) for a cross-platform
-solution in JavaScript, or check out either of these components for native
-solutions: [native-navigation](http://airbnb.io/native-navigation/),
-[react-native-navigation](https://github.com/wix/react-native-navigation).
-
-To set up the navigator, provide the `initialRoute` prop with a route
-object. A route object is used to describe each scene that your app
-navigates to. `initialRoute` represents the first route in your navigator.
+`NavigatorIOS` is a wrapper around [`UINavigationController`](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UINavigationController_Class/), enabling you to implement a navigation stack. It works exactly the same as it would on a native app using `UINavigationController`, providing the same animations and behavior from UIKit.
+
+As the name implies, it is only available on iOS. Take a look at [`React Navigation`](https://reactnavigation.org/) for a cross-platform solution in JavaScript, or check out either of these components for native solutions: [native-navigation](http://airbnb.io/native-navigation/), [react-native-navigation](https://github.com/wix/react-native-navigation).
+
+To set up the navigator, provide the `initialRoute` prop with a route object. A route object is used to describe each scene that your app navigates to. `initialRoute` represents the first route in your navigator.
```
import PropTypes from 'prop-types';
@@ -67,13 +57,9 @@ class MyScene extends Component {
}
```
-In this code, the navigator renders the component specified in initialRoute,
-which in this case is `MyScene`. This component will receive a `route` prop
-and a `navigator` prop representing the navigator. The navigator's navigation
-bar will render the title for the current scene, "My Initial Scene".
+In this code, the navigator renders the component specified in initialRoute, which in this case is `MyScene`. This component will receive a `route` prop and a `navigator` prop representing the navigator. The navigator's navigation bar will render the title for the current scene, "My Initial Scene".
-You can optionally pass in a `passProps` property to your `initialRoute`.
-`NavigatorIOS` passes this in as props to the rendered component:
+You can optionally pass in a `passProps` property to your `initialRoute`. `NavigatorIOS` passes this in as props to the rendered component:
```
initialRoute={{
@@ -87,10 +73,7 @@ You can then access the props passed in via `{this.props.myProp}`.
#### Handling Navigation
-To trigger navigation functionality such as pushing or popping a view, you
-have access to a `navigator` object. The object is passed in as a prop to any
-component that is rendered by `NavigatorIOS`. You can then call the
-relevant methods to perform the navigation action you need:
+To trigger navigation functionality such as pushing or popping a view, you have access to a `navigator` object. The object is passed in as a prop to any component that is rendered by `NavigatorIOS`. You can then call the relevant methods to perform the navigation action you need:
```
class MyView extends Component {
@@ -119,8 +102,7 @@ class MyView extends Component {
}
```
-You can also trigger navigator functionality from the `NavigatorIOS`
-component:
+You can also trigger navigator functionality from the `NavigatorIOS` component:
```
class NavvyIOS extends Component {
@@ -150,18 +132,11 @@ class NavvyIOS extends Component {
}
```
-The code above adds a `_handleNavigationRequest` private method that is
-invoked from the `NavigatorIOS` component when the right navigation bar item
-is pressed. To get access to the navigator functionality, a reference to it
-is saved in the `ref` prop and later referenced to push a new scene into the
-navigation stack.
+The code above adds a `_handleNavigationRequest` private method that is invoked from the `NavigatorIOS` component when the right navigation bar item is pressed. To get access to the navigator functionality, a reference to it is saved in the `ref` prop and later referenced to push a new scene into the navigation stack.
#### Navigation Bar Configuration
-Props passed to `NavigatorIOS` will set the default configuration
-for the navigation bar. Props passed as properties to a route object will set
-the configuration for that route's navigation bar, overriding any props
-passed to the `NavigatorIOS` component.
+Props passed to `NavigatorIOS` will set the default configuration for the navigation bar. Props passed as properties to a route object will set the configuration for that route's navigation bar, overriding any props passed to the `NavigatorIOS` component.
```
_handleNavigationRequest() {
@@ -183,8 +158,7 @@ render() {
}
```
-In the example above the navigation bar color is changed when the new route
-is pushed.
+In the example above the navigation bar color is changed when the new route is pushed.
### Props
@@ -228,14 +202,64 @@ is pushed.
NavigatorIOS uses `route` objects to identify child views, their props,
and navigation bar configuration. Navigation operations such as push
-operations expect routes to look like this the `initialRoute`.
+operations expect routes to look like this.
| Type | Required |
| - | - |
-| object: {component: function,title: string,titleImage: Image.propTypes.source,passProps: object,backButtonIcon: Image.propTypes.source,backButtonTitle: string,leftButtonIcon: Image.propTypes.source,leftButtonTitle: string,leftButtonSystemIcon: Object.keys(SystemIcons),onLeftButtonPress: function,rightButtonIcon: Image.propTypes.source,rightButtonTitle: string,rightButtonSystemIcon: Object.keys(SystemIcons),onRightButtonPress: function,wrapperStyle: ViewPropTypes.style,navigationBarHidden: bool,shadowHidden: bool,tintColor: string,barTintColor: string,barStyle: enum('default', 'black'),titleTextColor: string,translucent: bool} | Yes |
-
-
-
+| object | Yes |
+
+**Routes:**
+
+The following parameters can be used to define a route:
+
+* `**component**`: function
+ The React Class to render for this route.
+* `**title**`: string
+ The title displayed in the navigation bar and the back button for this route.
+* `**titleImage**`: [Image](docs/image.html)
+ If set, a title image will appear instead of the text title.
+* `**passProps**`: object
+ Use this to specify additional props to pass to the rendered component. `NavigatorIOS` will automatically pass in `route` and `navigator` props to the comoponent.
+* `**backButtonIcon**`: [Image](docs/image.html)
+ If set, the left navigation button image will be displayed using this source. Note that this doesn't apply to the header of the current view, but to those views that are subsequently pushed.
+* `**backButtonTitle**`: string
+ If set, the left navigation button text will be set to this. Note that this doesn't apply to the left button of the current view, but to those views that are subsequently pushed.
+* `**leftButtonIcon**`: [Image](docs/image.html)
+ If set, the left navigation button image will be displayed using this source.
+* `**leftButtonTitle**`: string
+ If set, the left navigation button will display this text.
+* `**leftButtonSystemIcon**`: [SystemIcon](docs/navigatorios.html#system-icons)
+ If set, the left header button will appear with this system icon. See below for supported icons.
+* `**onLeftButtonPress**`: function
+ This function will be invoked when the left navigation bar item is pressed.
+* `**rightButtonIcon**`: [Image](docs/image.html)
+ If set, the right navigation button image will be displayed using this source.
+* `**rightButtonTitle**`: string
+ If set, the right navigation button will display this text.
+* `**rightButtonSystemIcon**`: [SystemIcon](docs/navigatorios.html#system-icons)
+ If set, the right header button will appear with this system icon. See below for supported icons.
+* `**onRightButtonPress**`: function
+ This function will be invoked when the right navigation bar item is pressed.
+* `**wrapperStyle**`: [ViewPropTypes.style](docs/viewproptypes.html#style)
+ Styles for the navigation item containing the component.
+* `**navigationBarHidden**`: boolean
+ Boolean value that indicates whether the navigation bar is hidden.
+* `**shadowHidden**`: boolean
+ Boolean value that indicates whether to hide the 1px hairline shadow.
+* `**tintColor**`: string
+ The color used for the buttons in the navigation bar.
+* `**barTintColor**`: string
+ The background color of the navigation bar.
+* `**barStyle**`: enum('default', 'black')
+ The style of the navigation bar. Supported values are 'default', 'black'. Use 'black' instead of setting `barTintColor` to black. This produces a navigation bar with the native iOS style with higher translucency.
+* `**titleTextColor**`: string
+ The text color of the navigation bar title.
+* `**translucent**`: boolean
+ Boolean value that indicates whether the navigation bar is translucent.
+
+#### System Icons
+
+Used in `leftButtonSystemIcon` and `rightButtonSystemIcon`. Supported icons are `done`, `cancel`, `edit`, `save`, `add`, `compose`, `reply`, `action`, `organize`, `bookmarks`, `search`, `refresh`, `stop`, `camera`, `trash`, `play`, `pause`, `rewind`, `fast-forward`, `undo`, `redo`, and `page-curl`.
---
@@ -295,7 +319,7 @@ A common use case is to set the `backgroundColor` for every scene.
| Type | Required |
| - | - |
-| ViewPropTypes.style | No |
+| [ViewPropTypes.style](docs/viewproptypes.html#style) | No |
@@ -384,7 +408,7 @@ Navigate forward to a new route.
| Name | Type | Required | Description |
| - | - | - | - |
-| route | object | No | The new route to navigate to. |
+| route | object | Yes | The new route to navigate to. |
@@ -403,7 +427,7 @@ Go back N scenes at once. When N=1, behavior matches `pop()`.
| Name | Type | Required | Description |
| - | - | - | - |
-| n | number | No | The number of scenes to pop. |
+| n | number | Yes | The number of scenes to pop. |
@@ -434,8 +458,8 @@ Replace a route in the navigation stack.
| Name | Type | Required | Description |
| - | - | - | - |
-| route | object | No | The new route that will replace the specified one. |
-| index | number | No | The route into the stack that should be replaced. If it is negative, it counts from the back of the stack. |
+| route | object | Yes | The new route that will replace the specified one. |
+| index | number | Yes | The route into the stack that should be replaced. If it is negative, it counts from the back of the stack. |
@@ -455,7 +479,7 @@ load the view for the new route.
| Name | Type | Required | Description |
| - | - | - | - |
-| route | object | No | The new route to navigate to. |
+| route | object | Yes | The new route to navigate to. |
@@ -474,7 +498,7 @@ Replace the route/view for the previous scene.
| Name | Type | Required | Description |
| - | - | - | - |
-| route | object | No | The new route to will replace the previous scene. |
+| route | object | Yes | The new route to will replace the previous scene. |
@@ -505,7 +529,7 @@ Go back to the item for a particular route object.
| Name | Type | Required | Description |
| - | - | - | - |
-| route | object | No | The new route to navigate to. |
+| route | object | Yes | The new route to navigate to. |
@@ -524,7 +548,7 @@ Replaces the previous route/view and transitions back to it.
| Name | Type | Required | Description |
| - | - | - | - |
-| route | object | No | The new route that replaces the previous scene. |
+| route | object | Yes | The new route that replaces the previous scene. |
@@ -543,7 +567,7 @@ Replaces the top item and pop to it.
| Name | Type | Required | Description |
| - | - | - | - |
-| route | object | No | The new route that will replace the topmost item. |
+| route | object | Yes | The new route that will replace the topmost item. |
diff --git a/docs/netinfo.md b/docs/netinfo.md
index 4f8cd6c6d111a8..2d7eb73e44c029 100644
--- a/docs/netinfo.md
+++ b/docs/netinfo.md
@@ -8,7 +8,7 @@ next: panresponder
previous: linking
---
-NetInfo exposes info about online/offline status
+NetInfo exposes info about online/offline status.
```
NetInfo.getConnectionInfo().then((connectionInfo) => {
@@ -57,44 +57,6 @@ app's `AndroidManifest.xml`:
``
-### isConnectionExpensive
-
-Available on Android. Detect if the current active connection is metered or not. A network is
-classified as metered when the user is sensitive to heavy data usage on that connection due to
-monetary costs, data limitations or battery/performance issues.
-
-```
-NetInfo.isConnectionExpensive()
-.then(isConnectionExpensive => {
- console.log('Connection is ' + (isConnectionExpensive ? 'Expensive' : 'Not Expensive'));
-})
-.catch(error => {
- console.error(error);
-});
-```
-
-### isConnected
-
-Available on all platforms. Asynchronously fetch a boolean to determine
-internet connectivity.
-
-```
-NetInfo.isConnected.fetch().then(isConnected => {
- console.log('First, is ' + (isConnected ? 'online' : 'offline'));
-});
-function handleFirstConnectivityChange(isConnected) {
- console.log('Then, is ' + (isConnected ? 'online' : 'offline'));
- NetInfo.isConnected.removeEventListener(
- 'connectionChange',
- handleFirstConnectivityChange
- );
-}
-NetInfo.isConnected.addEventListener(
- 'connectionChange',
- handleFirstConnectivityChange
-);
-```
-
### Connectivity Types (deprecated)
The following connectivity types are deprecated. They're used by the deprecated APIs `fetch` and the `change` event.
@@ -148,7 +110,7 @@ The rest of the connectivity types are hidden by the Android API, but can be use
### `addEventListener()`
```javascript
-static addEventListener(eventName, handler)
+NetInfo.addEventListener(eventName, handler)
```
@@ -170,7 +132,7 @@ Adds an event handler. Supported events:
### `removeEventListener()`
```javascript
-static removeEventListener(eventName, handler)
+NetInfo.removeEventListener(eventName, handler)
```
@@ -184,7 +146,7 @@ Removes the listener for network status changes.
### `fetch()`
```javascript
-static fetch()
+NetInfo.fetch()
```
@@ -199,7 +161,7 @@ resolves with one of the deprecated connectivity types listed above.
### `getConnectionInfo()`
```javascript
-static getConnectionInfo()
+NetInfo.getConnectionInfo()
```
@@ -215,12 +177,44 @@ respectively.
### `isConnectionExpensive()`
```javascript
-static isConnectionExpensive()
+NetInfo.isConnectionExpensive()
+```
+
+Available on Android. Detect if the current active connection is metered or not. A network is
+classified as metered when the user is sensitive to heavy data usage on that connection due to
+monetary costs, data limitations or battery/performance issues.
+
+```
+NetInfo.isConnectionExpensive()
+.then(isConnectionExpensive => {
+ console.log('Connection is ' + (isConnectionExpensive ? 'Expensive' : 'Not Expensive'));
+})
+.catch(error => {
+ console.error(error);
+});
```
## Properties
+### `isConnected`
+Available on all platforms. Asynchronously fetch a boolean to determine internet connectivity.
+```
+NetInfo.isConnected.fetch().then(isConnected => {
+ console.log('First, is ' + (isConnected ? 'online' : 'offline'));
+});
+function handleFirstConnectivityChange(isConnected) {
+ console.log('Then, is ' + (isConnected ? 'online' : 'offline'));
+ NetInfo.isConnected.removeEventListener(
+ 'connectionChange',
+ handleFirstConnectivityChange
+ );
+}
+NetInfo.isConnected.addEventListener(
+ 'connectionChange',
+ handleFirstConnectivityChange
+);
+```
diff --git a/docs/panresponder.md b/docs/panresponder.md
index 5bb6d7b71de810..35ed082b31c5fd 100644
--- a/docs/panresponder.md
+++ b/docs/panresponder.md
@@ -121,41 +121,31 @@ To see it in action, try the
### `create()`
```javascript
-static create(config)
+PanResponder.create(config)
```
-
-@param {object} config Enhanced versions of all of the responder callbacks
-that provide not only the typical `ResponderSyntheticEvent`, but also the
-`PanResponder` gesture state. Simply replace the word `Responder` with
-`PanResponder` in each of the typical `onResponder*` callbacks. For
-example, the `config` object would look like:
-
- - `onMoveShouldSetPanResponder: (e, gestureState) => {...}`
- - `onMoveShouldSetPanResponderCapture: (e, gestureState) => {...}`
- - `onStartShouldSetPanResponder: (e, gestureState) => {...}`
- - `onStartShouldSetPanResponderCapture: (e, gestureState) => {...}`
- - `onPanResponderReject: (e, gestureState) => {...}`
- - `onPanResponderGrant: (e, gestureState) => {...}`
- - `onPanResponderStart: (e, gestureState) => {...}`
- - `onPanResponderEnd: (e, gestureState) => {...}`
- - `onPanResponderRelease: (e, gestureState) => {...}`
- - `onPanResponderMove: (e, gestureState) => {...}`
- - `onPanResponderTerminate: (e, gestureState) => {...}`
- - `onPanResponderTerminationRequest: (e, gestureState) => {...}`
- - `onShouldBlockNativeResponder: (e, gestureState) => {...}`
-
- In general, for events that have capture equivalents, we update the
- gestureState once in the capture phase and can use it in the bubble phase
- as well.
-
- Be careful with onStartShould* callbacks. They only reflect updated
- `gestureState` for start/end events that bubble/capture to the Node.
- Once the node is the responder, you can rely on every start/end event
- being processed by the gesture and `gestureState` being updated
- accordingly. (numberActiveTouches) may not be totally accurate unless you
- are the responder.
-
-
+Enhanced versions of all of the responder callbacks
+that provide not only the typical `ResponderSyntheticEvent`, but also the `PanResponder` gesture state. Simply replace the word `Responder` with
+`PanResponder` in each of the typical `onResponder*` callbacks.
+
+For example, the `config` object would look like:
+
+- `onMoveShouldSetPanResponder: (e, gestureState) => {...}`
+- `onMoveShouldSetPanResponderCapture: (e, gestureState) => {...}`
+- `onStartShouldSetPanResponder: (e, gestureState) => {...}`
+- `onStartShouldSetPanResponderCapture: (e, gestureState) => {...}`
+- `onPanResponderReject: (e, gestureState) => {...}`
+- `onPanResponderGrant: (e, gestureState) => {...}`
+- `onPanResponderStart: (e, gestureState) => {...}`
+- `onPanResponderEnd: (e, gestureState) => {...}`
+- `onPanResponderRelease: (e, gestureState) => {...}`
+- `onPanResponderMove: (e, gestureState) => {...}`
+- `onPanResponderTerminate: (e, gestureState) => {...}`
+- `onPanResponderTerminationRequest: (e, gestureState) => {...}`
+- `onShouldBlockNativeResponder: (e, gestureState) => {...}`
+
+In general, for events that have capture equivalents, we update the gestureState once in the capture phase and can use it in the bubble phase as well.
+
+Be careful with onStartShould* callbacks. They only reflect updated `gestureState` for start/end events that bubble/capture to the Node. Once the node is the responder, you can rely on every start/end event being processed by the gesture and `gestureState` being updated accordingly. (numberActiveTouches) may not be totally accurate unless you are the responder.
diff --git a/docs/permissionsandroid.md b/docs/permissionsandroid.md
index e136da5a555019..e56db936decfa1 100644
--- a/docs/permissionsandroid.md
+++ b/docs/permissionsandroid.md
@@ -19,23 +19,16 @@ previous: panresponder
-`PermissionsAndroid` provides access to Android M's new permissions model.
-Some permissions are granted by default when the application is installed
-so long as they appear in `AndroidManifest.xml`. However, "dangerous"
-permissions require a dialog prompt. You should use this module for those
+`PermissionsAndroid` provides access to Android M's new permissions model. Some permissions are granted by default when the application is installed so long as they appear in `AndroidManifest.xml`. However, "dangerous" permissions require a dialog prompt. You should use this module for those
permissions.
-On devices before SDK version 23, the permissions are automatically granted
-if they appear in the manifest, so `check` and `request`
-should always be true.
+On devices before SDK version 23, the permissions are automatically granted if they appear in the manifest, so `check` and `request` should always be true.
-If a user has previously turned off a permission that you prompt for, the OS
-will advise your app to show a rationale for needing the permission. The
-optional `rationale` argument will show a dialog prompt only if
-necessary - otherwise the normal permission prompt will appear.
+If a user has previously turned off a permission that you prompt for, the OS will advise your app to show a rationale for needing the permission. The optional `rationale` argument will show a dialog prompt only if necessary - otherwise the normal permission prompt will appear.
### Example
-```
+
+```javascript
import { PermissionsAndroid } from 'react-native';
async function requestCameraPermission() {
@@ -63,11 +56,11 @@ async function requestCameraPermission() {
### Methods
- [`constructor`](docs/permissionsandroid.html#constructor)
-- [`checkPermission`](docs/permissionsandroid.html#checkpermission)
- [`check`](docs/permissionsandroid.html#check)
-- [`requestPermission`](docs/permissionsandroid.html#requestpermission)
- [`request`](docs/permissionsandroid.html#request)
- [`requestMultiple`](docs/permissionsandroid.html#requestmultiple)
+- [`requestPermission`](docs/permissionsandroid.html#requestpermission)
+- [`checkPermission`](docs/permissionsandroid.html#checkpermission)
@@ -88,97 +81,71 @@ constructor()
---
-### `checkPermission()`
+### `check()`
```javascript
-checkPermission(permission)
+check(permission)
```
-DEPRECATED - use check
-
-Returns a promise resolving to a boolean value as to whether the specified
-permissions has been granted
-
-@deprecated
-
-
+Returns a promise resolving to a boolean value as to whether the specified permissions has been granted
---
-### `check()`
+### `request()`
```javascript
-check(permission)
+request(permission, rationale?)
```
-Returns a promise resolving to a boolean value as to whether the specified
-permissions has been granted
+Prompts the user to enable a permission and returns a promise resolving to a string value indicating whether the user allowed or denied the request.
+
+If the optional rationale argument is included (which is an object with a `title` and `message`), this function checks with the OS whether it is necessary to show a dialog [explaining why the permission is needed](https://developer.android.com/training/permissions/requesting.html#explain) and then shows the system permission dialog
---
-### `requestPermission()`
+### `requestMultiple()`
```javascript
-requestPermission(permission, rationale?)
+requestMultiple(permissions)
```
-DEPRECATED - use request
-
-Prompts the user to enable a permission and returns a promise resolving to a
-boolean value indicating whether the user allowed or denied the request
-
-If the optional rationale argument is included (which is an object with a
-`title` and `message`), this function checks with the OS whether it is
-necessary to show a dialog explaining why the permission is needed
-(https://developer.android.com/training/permissions/requesting.html#explain)
-and then shows the system permission dialog
-
-@deprecated
-
-
+Prompts the user to enable multiple permissions in the same dialog and returns an object with the permissions as keys and strings as values indicating whether the user allowed or denied the request
---
-### `request()`
+### `checkPermission()`
```javascript
-request(permission, rationale?)
+checkPermission(permission)
```
-Prompts the user to enable a permission and returns a promise resolving to a
-string value indicating whether the user allowed or denied the request
-
-If the optional rationale argument is included (which is an object with a
-`title` and `message`), this function checks with the OS whether it is
-necessary to show a dialog explaining why the permission is needed
-(https://developer.android.com/training/permissions/requesting.html#explain)
-and then shows the system permission dialog
+**DEPRECATED** - use [check](docs/permissionsandroid.html#check)
+Returns a promise resolving to a boolean value as to whether the specified permissions has been granted
---
-### `requestMultiple()`
+### `requestPermission()`
```javascript
-requestMultiple(permissions)
+requestPermission(permission, rationale?)
```
-Prompts the user to enable multiple permissions in the same dialog and
-returns an object with the permissions as keys and strings as values
-indicating whether the user allowed or denied the request
-
+**DEPRECATED** - use [request](docs/permissionsandroid.html#request)
+Prompts the user to enable a permission and returns a promise resolving to a boolean value indicating whether the user allowed or denied the request.
+If the optional rationale argument is included (which is an object with a `title` and `message`), this function checks with the OS whether it is necessary to show a dialog [explaining why the permission is needed](https://developer.android.com/training/permissions/requesting.html#explain) and then shows the system permission dialog
diff --git a/docs/picker-item.md b/docs/picker-item.md
new file mode 100644
index 00000000000000..6e1481d153c9ae
--- /dev/null
+++ b/docs/picker-item.md
@@ -0,0 +1,57 @@
+---
+id: picker-item
+title: Picker.Item
+layout: docs
+category: components
+permalink: docs/picker-item.html
+next: pickerios
+previous: picker
+---
+
+Individual selectable item in a [Picker](docs/picker.html).
+
+### Props
+
+- [`label`](docs/picker-item.html#label)
+- [`color`](docs/picker-item.html#color)
+- [`testID`](docs/picker-item.html#testid)
+- [`value`](docs/picker-item.html#value)
+
+---
+
+# Reference
+
+## Props
+
+### `label`
+
+Text to display for this item.
+
+| Type | Required |
+| - | - |
+| string | Yes |
+
+### `color`
+
+The value to be passed to picker's `onValueChange` callback when this item is selected. Can be a string or an integer.
+
+| Type | Required |
+| - | - |
+| [color](docs/colors.html) | No |
+
+### `testID`
+
+Used to locate the item in end-to-end tests.
+
+| Type | Required |
+| - | - |
+| string | No |
+
+### `value`
+
+Color of this item's text.
+
+| Type | Required | Platform |
+| - | - | - |
+| any | No | Android |
+
diff --git a/docs/picker-style-props.md b/docs/picker-style-props.md
new file mode 100644
index 00000000000000..b9df932a5ba5d0
--- /dev/null
+++ b/docs/picker-style-props.md
@@ -0,0 +1,32 @@
+---
+id: picker-style-props
+title: Picker Style Props
+layout: docs
+category: APIs
+permalink: docs/picker-style-props.html
+next: shadow-props
+previous: layout-props
+---
+
+[Picker](docs/picker.html) style props.
+
+### Props
+
+- [View Style Props...](docs/view-style-props.html)
+- [`color`](docs/picker-style-props.html#color)
+
+
+
+---
+
+# Reference
+
+## Props
+
+### `color`
+
+
+
+| Type | Required |
+| - | - |
+| [color](docs/color.html) | No |
diff --git a/docs/picker.md b/docs/picker.md
index 94918d361edb3e..3ce067f96643c3 100644
--- a/docs/picker.md
+++ b/docs/picker.md
@@ -4,9 +4,10 @@ title: Picker
layout: docs
category: components
permalink: docs/picker.html
-next: pickerios
+next: picker-item
previous: navigatorios
---
+
Renders the native picker component on iOS and Android. Example:
Display > Font size, on iOS it will always return the default pixel ratio.
-@platform android
-
+Currently this is only implemented on Android and reflects the user preference set in Settings > Display > Font size, on iOS it will always return the default pixel ratio.
+| Platform |
+| - |
+| Android |
---
@@ -123,10 +122,9 @@ Settings > Display > Font size, on iOS it will always return the default pixel r
### `getPixelSizeForLayoutSize()`
```javascript
-static getPixelSizeForLayoutSize(layoutSize)
+PixelRatio.getPixelSizeForLayoutSize(layoutSize)
```
-
Converts a layout size (dp) to pixel size (px).
Guaranteed to return an integer number.
@@ -139,27 +137,9 @@ Guaranteed to return an integer number.
### `roundToNearestPixel()`
```javascript
-static roundToNearestPixel(layoutSize)
-```
-
-
-Rounds a layout size (dp) to the nearest layout size that corresponds to
-an integer number of pixels. For example, on a device with a PixelRatio
-of 3, `PixelRatio.roundToNearestPixel(8.4) = 8.33`, which corresponds to
-exactly (8.33 * 3) = 25 pixels.
-
-
-
-
----
-
-### `startDetecting()`
-
-```javascript
-static startDetecting()
+PixelRatio.roundToNearestPixel(layoutSize)
```
-// No-op for iOS, but used on the web. Should not be documented.
-
+Rounds a layout size (dp) to the nearest layout size that corresponds to an integer number of pixels. For example, on a device with a PixelRatio of 3, `PixelRatio.roundToNearestPixel(8.4) = 8.33`, which corresponds to exactly (8.33 * 3) = 25 pixels.
diff --git a/docs/progressbarandroid.md b/docs/progressbarandroid.md
index ba0232410c0df3..b316ea1224130a 100644
--- a/docs/progressbarandroid.md
+++ b/docs/progressbarandroid.md
@@ -31,7 +31,7 @@ render: function() {
### Props
-* [ViewPropTypes props...](docs/viewproptypes.html#props)
+- [View props...](docs/view-props.html)
- [`animating`](docs/progressbarandroid.html#animating)
- [`color`](docs/progressbarandroid.html#color)
- [`indeterminate`](docs/progressbarandroid.html#indeterminate)
@@ -107,13 +107,13 @@ The progress value (between 0 and 1).
Style of the ProgressBar. One of:
-- Horizontal
-- Normal (default)
-- Small
-- Large
-- Inverse
-- SmallInverse
-- LargeInverse
+- `Horizontal`
+- `Normal` (default)
+- `Small`
+- `Large`
+- `Inverse`
+- `SmallInverse`
+- `LargeInverse`
| Type | Required |
| - | - |
diff --git a/docs/progressviewios.md b/docs/progressviewios.md
index bc8cd300b2f25f..b9c9bdedb27ece 100644
--- a/docs/progressviewios.md
+++ b/docs/progressviewios.md
@@ -11,7 +11,7 @@ Use `ProgressViewIOS` to render a UIProgressView on iOS.
### Props
-* [ViewPropTypes props...](docs/viewproptypes.html#props)
+- [View props...](docs/view-props.html)
- [`progress`](docs/progressviewios.html#progress)
- [`progressImage`](docs/progressviewios.html#progressimage)
- [`progressTintColor`](docs/progressviewios.html#progresstintcolor)
diff --git a/docs/pushnotificationios.md b/docs/pushnotificationios.md
index b452ffdcdb4e23..1093e3da9d5e69 100644
--- a/docs/pushnotificationios.md
+++ b/docs/pushnotificationios.md
@@ -70,7 +70,7 @@ And then in your AppDelegate implementation add the following:
### Methods
-- [`=`](docs/pushnotificationios.html#)
+- [`presentLocalNotification`](docs/pushnotificationios.html#presentlocalnotification)
- [`scheduleLocalNotification`](docs/pushnotificationios.html#schedulelocalnotification)
- [`cancelAllLocalNotifications`](docs/pushnotificationios.html#cancelalllocalnotifications)
- [`removeAllDeliveredNotifications`](docs/pushnotificationios.html#removealldeliverednotifications)
@@ -96,8 +96,9 @@ And then in your AppDelegate implementation add the following:
- [`getBadgeCount`](docs/pushnotificationios.html#getbadgecount)
- [`getData`](docs/pushnotificationios.html#getdata)
+## Events
-
+- [PushNotificationEventName](docs/pushnotificationios.html#pushnotificationeventname)
---
@@ -105,12 +106,23 @@ And then in your AppDelegate implementation add the following:
## Methods
-### `=()`
+### `presentLocalNotification()`
```javascript
-=(NewData, NoData, ResultFailed, }, static, (, :)
+presentLocalNotification(details)
```
+Schedules the localNotification for immediate presentation.
+
+`details` is an object containing:
+
+- `alertBody` : The message displayed in the notification alert.
+- `alertAction` : The "action" displayed beneath an actionable notification. Defaults to "view";
+- `soundName` : The sound played when the notification is fired (optional).
+- `isSilent` : If true, the notification will appear without sound (optional).
+- `category` : The category of this notification, required for actionable notifications (optional).
+- `userInfo` : An optional object containing additional notification data.
+- `applicationIconBadgeNumber` (optional) : The number to display as the app's icon badge. The default value of this property is 0, which means that no badge is displayed.
---
@@ -177,18 +189,22 @@ static getDeliveredNotifications(callback)
```
-Provides you with a list of the app’s notifications that are still displayed in Notification Center
+Provides you with a list of the app’s notifications that are still displayed in Notification Center.
-@param callback Function which receive an array of delivered notifications
+A delivered notification is an object containing:
- A delivered notification is an object containing:
+- `identifier`: The identifier of this notification.
+- `title`: The title of this notification.
+- `body`: The body of this notification.
+- `category`: The category of this notification, if has one.
+- `userInfo`: An optional object containing additional notification data.
+- `thread-id`: The thread identifier of this notification, if has one.
-- `identifier` : The identifier of this notification.
-- `title` : The title of this notification.
-- `body` : The body of this notification.
-- `category` : The category of this notification, if has one.
-- `userInfo` : An optional object containing additional notification data.
-- `thread-id` : The thread identifier of this notification, if has one.
+**Parameters:**
+
+| Name | Type | Required | Description |
+| - | - | - | - |
+| callback | function | Yes | Function which receives an array of delivered notifications. |
@@ -201,11 +217,13 @@ Provides you with a list of the app’s notifications that are still displayed i
static removeDeliveredNotifications(identifiers)
```
+Removes the specified notifications from Notification Center.
-Removes the specified notifications from Notification Center
-
-@param identifiers Array of notification identifiers
+**Parameters:**
+| Name | Type | Required | Description |
+| - | - | - | - |
+| identifiers | array | Yes | Array of notification identifiers |
@@ -403,9 +421,7 @@ constructor(nativeNotif)
```
-You will never need to instantiate `PushNotificationIOS` yourself.
-Listening to the `notification` event and invoking
-`getInitialNotification` is sufficient
+You will never need to instantiate `PushNotificationIOS` yourself. Listening to the `notification` event and invoking `getInitialNotification` is sufficient.
@@ -419,19 +435,11 @@ finish(fetchResult)
```
-This method is available for remote notifications that have been received via:
-`application:didReceiveRemoteNotification:fetchCompletionHandler:`
-https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/#//apple_ref/occ/intfm/UIApplicationDelegate/application:didReceiveRemoteNotification:fetchCompletionHandler:
-
-Call this to execute when the remote notification handling is complete. When
-calling this block, pass in the fetch result value that best describes
-the results of your operation. You *must* call this handler and should do so
-as soon as possible. For a list of possible values, see `PushNotificationIOS.FetchResult`.
-
-If you do not call this method your background remote notifications could
-be throttled, to read more about it see the above documentation link.
+This method is available for remote notifications that have been received via [`application:didReceiveRemoteNotification:fetchCompletionHandler:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623013-application).
+Call this to execute when the remote notification handling is complete. When calling this block, pass in the fetch result value that best describes the results of your operation. You *must* call this handler and should do so as soon as possible. For a list of possible values, see `PushNotificationIOS.FetchResult`.
+If you do not call this method your background remote notifications could be throttled, to read more about it see the above documentation link.
---
@@ -531,4 +539,13 @@ Gets the data object on the notif
+## Events
+
+### `PushNotificationEventName`
+
+An event emitted by PushNotificationIOS.
+- `notification` - Fired when a remote notification is received. The handler will be invoked with an instance of `PushNotificationIOS`.
+- `localNotification` - Fired when a local notification is received. The handler will be invoked with an instance of `PushNotificationIOS`.
+- `register` - Fired when the user registers for remote notifications. The handler will be invoked with a hex string representing the deviceToken.
+- `registrationError` - Fired when the user fails to register for remote notifications. Typically occurs when APNS is having issues, or the device is a emulator. The handler will be invoked with `{message: string, code: number, details: any}`.
\ No newline at end of file
diff --git a/docs/refreshcontrol.md b/docs/refreshcontrol.md
index d6ec9ce66827ec..6302f46297bb9e 100644
--- a/docs/refreshcontrol.md
+++ b/docs/refreshcontrol.md
@@ -53,7 +53,7 @@ in the `onRefresh` function otherwise the refresh indicator will stop immediatel
### Props
-* [ViewPropTypes props...](docs/viewproptypes.html#props)
+- [View props...](docs/view-props.html)
- [`refreshing`](docs/refreshcontrol.html#refreshing)
- [`onRefresh`](docs/refreshcontrol.html#onrefresh)
- [`colors`](docs/refreshcontrol.html#colors)
diff --git a/docs/runningondeviceandroid.md b/docs/runningondeviceandroid.md
new file mode 100644
index 00000000000000..7af98dc23aaa57
--- /dev/null
+++ b/docs/runningondeviceandroid.md
@@ -0,0 +1,8 @@
+---
+id: running-on-device-android
+title: Running On Device
+layout: redirect
+permalink: docs/running-on-device-android.html
+destinationUrl: running-on-device.html
+---
+Redirecting...
\ No newline at end of file
diff --git a/docs/runningondeviceios.md b/docs/runningondeviceios.md
new file mode 100644
index 00000000000000..3b367bc049a82b
--- /dev/null
+++ b/docs/runningondeviceios.md
@@ -0,0 +1,8 @@
+---
+id: running-on-device-ios
+title: Running On Device
+layout: redirect
+permalink: docs/running-on-device-ios.html
+destinationUrl: running-on-device.html
+---
+Redirecting...
\ No newline at end of file
diff --git a/docs/scrollview.md b/docs/scrollview.md
index 276582ca01f113..c73e45955333b0 100644
--- a/docs/scrollview.md
+++ b/docs/scrollview.md
@@ -43,7 +43,7 @@ supports out of the box.
### Props
-* [ViewPropTypes props...](docs/viewproptypes.html#props)
+- [View props...](docs/view-props.html)
- [`alwaysBounceVertical`](docs/scrollview.html#alwaysbouncevertical)
- [`contentContainerStyle`](docs/scrollview.html#contentcontainerstyle)
- [`keyboardDismissMode`](docs/scrollview.html#keyboarddismissmode)
@@ -62,7 +62,6 @@ supports out of the box.
- [`endFillColor`](docs/scrollview.html#endfillcolor)
- [`overScrollMode`](docs/scrollview.html#overscrollmode)
- [`scrollPerfTag`](docs/scrollview.html#scrollperftag)
-- [`DEPRECATED_sendUpdatedChildFrames`](docs/scrollview.html#deprecated-sendupdatedchildframes)
- [`alwaysBounceHorizontal`](docs/scrollview.html#alwaysbouncehorizontal)
- [`horizontal`](docs/scrollview.html#horizontal)
- [`automaticallyAdjustContentInsets`](docs/scrollview.html#automaticallyadjustcontentinsets)
@@ -85,6 +84,7 @@ supports out of the box.
- [`snapToAlignment`](docs/scrollview.html#snaptoalignment)
- [`snapToInterval`](docs/scrollview.html#snaptointerval)
- [`zoomScale`](docs/scrollview.html#zoomscale)
+- [`DEPRECATED_sendUpdatedChildFrames`](docs/scrollview.html#deprecated-sendupdatedchildframes)
@@ -141,7 +141,7 @@ const styles = StyleSheet.create({
| Type | Required |
| - | - |
-| StyleSheetPropType(ViewStylePropTypes) | No |
+| [style](docs/view-style-props.html) | No |
@@ -417,25 +417,6 @@ FpsListener for it to be useful.
-
----
-
-### `DEPRECATED_sendUpdatedChildFrames`
-
-When true, ScrollView will emit updateChildFrames data in scroll events,
-otherwise will not compute or emit child frame data. This only exists
-to support legacy issues, `onLayout` should be used instead to retrieve
-frame data.
-The default value is false.
-
-
-| Type | Required | Platform |
-| - | - | - |
-| bool | No | iOS |
-
-
-
-
---
### `alwaysBounceHorizontal`
@@ -796,6 +777,20 @@ The current scale of the scroll view content. The default value is 1.0.
| number | No | iOS |
+---
+
+### `DEPRECATED_sendUpdatedChildFrames`
+
+**Deprecated.** When true, ScrollView will emit updateChildFrames data in scroll events,
+otherwise will not compute or emit child frame data. This only exists
+to support legacy issues, `onLayout` should be used instead to retrieve
+frame data.
+The default value is false.
+
+
+| Type | Required | Platform |
+| - | - | - |
+| bool | No | iOS |
diff --git a/docs/sectionlist.md b/docs/sectionlist.md
index b6dced3898c348..d7bca81aa9ce96 100644
--- a/docs/sectionlist.md
+++ b/docs/sectionlist.md
@@ -7,6 +7,7 @@ permalink: docs/sectionlist.html
next: segmentedcontrolios
previous: scrollview
---
+
A performant interface for rendering sectioned lists, supporting the most handy features:
- Fully cross-platform.
@@ -25,46 +26,60 @@ If you don't need section support and want a simpler interface, use
Simple Examples:
- }
- renderSectionHeader={({section}) => }
- sections={[ // homogeneous rendering between sections
- {data: [...], title: ...},
- {data: [...], title: ...},
- {data: [...], title: ...},
- ]}
- />
-
-
-
-This is a convenience wrapper around [``](docs/virtualizedlist.html),
+```javascript
+}
+ renderSectionHeader={({section}) => }
+ sections={[ // homogeneous rendering between sections
+ {data: [...], title: ...},
+ {data: [...], title: ...},
+ {data: [...], title: ...},
+ ]}
+/>
+
+
+```
+
+This is a convenience wrapper around [`VirtualizedList`](docs/virtualizedlist.html),
and thus inherits its props (as well as those of `ScrollView`) that aren't explicitly listed
here, along with the following caveats:
-- Internal state is not preserved when content scrolls out of the render window. Make sure all
- your data is captured in the item data or external stores like Flux, Redux, or Relay.
-- This is a `PureComponent` which means that it will not re-render if `props` remain shallow-
- equal. Make sure that everything your `renderItem` function depends on is passed as a prop
- (e.g. `extraData`) that is not `===` after updates, otherwise your UI may not update on
- changes. This includes the `data` prop and parent component state.
-- In order to constrain memory and enable smooth scrolling, content is rendered asynchronously
- offscreen. This means it's possible to scroll faster than the fill rate and momentarily see
- blank content. This is a tradeoff that can be adjusted to suit the needs of each application,
- and we are working on improving it behind the scenes.
-- By default, the list looks for a `key` prop on each item and uses that for the React key.
- Alternatively, you can provide a custom `keyExtractor` prop.
+- Internal state is not preserved when content scrolls out of the render window. Make sure all your data is captured in the item data or external stores like Flux, Redux, or Relay.
+- This is a `PureComponent` which means that it will not re-render if `props` remain shallow- equal. Make sure that everything your `renderItem` function depends on is passed as a prop (e.g. `extraData`) that is not `===` after updates, otherwise your UI may not update on changes. This includes the `data` prop and parent component state.
+- In order to constrain memory and enable smooth scrolling, content is rendered asynchronously offscreen. This means it's possible to scroll faster than the fill rate and momentarily see blank content. This is a tradeoff that can be adjusted to suit the needs of each application, and we are working on improving it behind the scenes.
+- By default, the list looks for a `key` prop on each item and uses that for the React key. Alternatively, you can provide a custom `keyExtractor` prop.
### Props
+- [`ScrollView` props...](docs/scrollview.html#props)
+- [`VirtualizedList` props...](docs/virtualizedlist.html#props)
+- [`sections`](docs/virtualizedlist.html#sections)
+- [`renderItem`](docs/virtualizedlist.html#renderitem)
+- [`ItemSeparatorComponent`](docs/virtualizedlist.html#itemseparatorcomponent)
+- [`ItemSeparatorComponent`](docs/virtualizedlist.html#itemseparatorcomponent)
+- [`ListEmptyComponent`](docs/virtualizedlist.html#listemptycomponent)
+- [`ListFooterComponent`](docs/virtualizedlist.html#listgootercomponent)
+SectionSeparatorComponent
+- [`extradata`](docs/virtualizedlist.html#extradata)
+- [`initialNumToRender`](docs/virtualizedlist.html#initialnumtorender)
+- [`inverted`](docs/virtualizedlist.html#inverted)
+- [`keyExtractor`](docs/virtualizedlist.html#keyextractor)
+- [`onEndReached`](docs/virtualizedlist.html#onendreached)
+- [`onEndReachedThreshold`](docs/virtualizedlist.html#onendreachedthreshold)
+- [`onRefresh`](docs/virtualizedlist.html#onrefresh)
+- [`onViewableItemsChanged`](docs/virtualizedlist.html#onviewableitemschanged)
+- [`refreshing`](docs/virtualizedlist.html#refreshing)
+- [`removeClippedSubviews`](docs/virtualizedlist.html#removeclippedsubviews)
+- [`renderSectionHeader`](docs/virtualizedlist.html#removeclippedsubviews)
+- [`renderSectionFooter`](docs/virtualizedlist.html#rendersectionfooter)
- [`stickySectionHeadersEnabled`](docs/sectionlist.html#stickysectionheadersenabled)
-
-
+- [`legacyImplementation`](docs/virtualizedlist.html#legacyimplementation)
### Methods
@@ -88,9 +103,302 @@ here, along with the following caveats:
## Props
-### `stickySectionHeadersEnabled`
+### `sections`
+
+The actual data to render, akin to the `data` prop in [`FlatList`](/docs/flatlist.html#data).
+
+**General shape:**
+
+```
+sections: [{
+ data: array,
+ [renderItem]: ({item: SectionItem, ...}) => element,
+ [ItemSeparatorComponent]: React Class Component | function | element,
+}]
+```
+
+| Type | Required |
+| - | - |
+| array of objects | Yes |
+
+
+
+---
+
+
+### `renderItem`
+
+```javascript
+renderItem({ item: object, index: number, section: object, separators: { highlight: function, unhighlight: function, updateProps: function(select: string, newProps: object) } }): [element]
+```
+
+Default renderer for every item in every section. Can be over-ridden on a per-section basis.
+
+Provides additional metadata like `index` if you need it, as well as a more generic `separators.updateProps` function which let's you set whatever props you want to change the rendering of either the leading separator or trailing separator in case the more common `highlight` and `unhighlight` (which set the `highlighted: boolean` prop) are insufficient for your use case.
+
+| Type | Required |
+| - | - |
+| function | No |
+
+
+
+---
+
+
+### `ItemSeparatorComponent`
+
+Rendered in between each item, but not at the top or bottom. By default, `highlighted`, `section`, and `[leading/trailing][Item/Separator]` props are provided. `renderItem` provides `separators.highlight`/`unhighlight` which will update the `highlighted` prop, but you can also add custom props with `separators.updateProps`.
+
+| Type | Required |
+| - | - |
+| component | No |
+
+
+
+---
+
+
+### `ListHeaderComponent`
+
+Rendered at the top of all the items. Can be a React Component Class, a render function, or a rendered element.
+
+| Type | Required |
+| - | - |
+| component, function, element | No |
+
+
+
+---
+
+
+### `ListEmptyComponent`
+
+Rendered when the list is empty. Can be a React Component Class, a render function, or a rendered element.
+
+| Type | Required |
+| - | - |
+| component, function, element | No |
+
+
+
+---
+
+
+### `ListFooterComponent`
+
+Rendered at the very end of the list. Can be a React Component Class, a render function, or a rendered element.
+
+| Type | Required |
+| - | - |
+| component, function, element | No |
+
+
+
+---
+
+
+### `SectionSeparatorComponent`
+
+Rendered at the top and bottom of each section (note this is different from `ItemSeparatorComponent` which is only rendered between items). These are intended to separate sections from the headers above and below and typically have the same highlight response as `ItemSeparatorComponent`. Also receives `highlighted`, `[leading/trailing][Item/Separator]`, and any custom props from `separators.updateProps`.
+
+| Type | Required |
+| - | - |
+| any | No |
+
+
+
+---
+
+
+### `extraData`
+
+A marker property for telling the list to re-render (since it implements `PureComponent`). If any of your `renderItem`, Header, Footer, etc. functions depend on anything outside of the `data` prop, stick it here and treat it immutably.
+
+| Type | Required |
+| - | - |
+| any | No |
+
+
+
+---
+
+
+### `initialNumToRender`
+
+How many items to render in the initial batch. This should be enough to fill the screen but not much more. Note these items will never be unmounted as part of the windowed rendering in order to improve perceived performance of scroll-to-top actions.
+
+| Type | Required |
+| - | - |
+| number | No |
+
+
+
+---
+
+
+### `inverted`
+
+Reverses the direction of scroll. Uses scale transforms of `-1`.
+
+| Type | Required |
+| - | - |
+| boolean | No |
+
+
+
+---
+
+
+### `keyExtractor`
+
+```javascript
+(item: object, index: number) => string
+```
+
+Used to extract a unique key for a given item at the specified index. Key is used for caching and as the react key to track item re-ordering. The default extractor checks item.key, then falls back to using the index, like react does. Note that this sets keys for each item, but each overall section still needs its own key.
+
+| Type | Required |
+| - | - |
+| function | No |
+
+
+
+---
+
+
+### `onEndReached`
+
+```javascript
+(info: {distanceFromEnd: number}) => void
+```
+
+Called once when the scroll position gets within `onEndReachedThreshold` of the rendered content.
+
+| Type | Required |
+| - | - |
+| function | No |
+
+
+
+---
+
+
+### `onEndReachedThreshold`
+
+ How far from the end (in units of visible length of the list) the bottom edge of the list must be from the end of the content to trigger the `onEndReached` callback. Thus a value of 0.5 will trigger `onEndReached` when the end of the content is within half the visible length of the list.
+
+| Type | Required |
+| - | - |
+| number | No |
+
+
+
+---
+
+
+### `onRefresh`
+
+```javascript
+() => void
+```
+
+If provided, a standard RefreshControl will be added for "Pull to Refresh" functionality. Make sure to also set the `refreshing` prop correctly.
+
+| Type | Required |
+| - | - |
+| function | No |
+
+
+
+---
+
+
+### `onViewableItemsChanged`
+
+```javascript
+(info: {
+ viewableItems: array,
+ changed: array,
+ }) => void
+```
+
+Called when the viewability of rows changes, as defined by the `viewabilityConfig` prop.
+| Type | Required |
+| - | - |
+| function | No |
+
+
+
+---
+
+
+### `refreshing`
+
+Set this true while waiting for new data from a refresh.
+
+| Type | Required |
+| - | - |
+| boolean | No |
+
+
+
+---
+
+
+### `removeClippedSubviews`
+
+This may improve scroll performance for large lists.
+
+> Note:
+> May have bugs (missing content) in some circumstances - use at your own risk.
+
+| Type | Required |
+| - | - |
+| boolean | No |
+
+
+
+---
+
+
+### `renderSectionHeader`
+
+```
+(info: {section}) => [element]
+```
+
+Rendered at the top of each section. These stick to the top of the `ScrollView` by default on iOS. See `stickySectionHeadersEnabled`.
+
+| Type | Required |
+| - | - |
+| element | No |
+
+
+
+---
+
+
+### `renderSectionFooter`
+
+```
+(info: {section}) => [element]
+```
+
+React element rendered at the bottom of each section.
+
+| Type | Required |
+| - | - |
+| element | No |
+
+
+
+---
+
+
+### `stickySectionHeadersEnabled`
+Makes section headers stick to the top of the screen until the next one pushes it off. Only enabled by default on iOS because that is the platform standard there.
| Type | Required |
| - | - |
diff --git a/docs/segmentedcontrolios.md b/docs/segmentedcontrolios.md
index 749517a97a4d4b..65d764193094a3 100644
--- a/docs/segmentedcontrolios.md
+++ b/docs/segmentedcontrolios.md
@@ -28,7 +28,7 @@ selects a value and changes the index, as shown in the example below.
### Props
-* [ViewPropTypes props...](docs/viewproptypes.html#props)
+- [View props...](docs/view-props.html)
- [`enabled`](docs/segmentedcontrolios.html#enabled)
- [`momentary`](docs/segmentedcontrolios.html#momentary)
- [`onChange`](docs/segmentedcontrolios.html#onchange)
diff --git a/docs/settings.md b/docs/settings.md
index 61b539f0bfb43e..9dc2b7e3aa4372 100644
--- a/docs/settings.md
+++ b/docs/settings.md
@@ -33,7 +33,7 @@ previous: pushnotificationios
### `get()`
```javascript
-static get(key)
+Settings.get(key)
```
@@ -43,7 +43,7 @@ static get(key)
### `set()`
```javascript
-static set(settings)
+Settings.set(settings)
```
@@ -53,7 +53,7 @@ static set(settings)
### `watchKeys()`
```javascript
-static watchKeys(keys, callback)
+Settings.watchKeys(keys, callback)
```
@@ -63,7 +63,7 @@ static watchKeys(keys, callback)
### `clearWatch()`
```javascript
-static clearWatch(watchId)
+Settings.clearWatch(watchId)
```
diff --git a/docs/shadow-props.md b/docs/shadow-props.md
index 3514190c4d5f8d..9616d4108aedcd 100644
--- a/docs/shadow-props.md
+++ b/docs/shadow-props.md
@@ -4,7 +4,7 @@ title: Shadow Props
layout: docs
category: APIs
permalink: docs/shadow-props.html
-next: viewproptypes
+next: view-props
previous: layout-props
---
### Props
diff --git a/docs/share.md b/docs/share.md
index 8ae16335289b0f..14c359bb6e16fd 100644
--- a/docs/share.md
+++ b/docs/share.md
@@ -28,15 +28,13 @@ previous: settings
### `share()`
```javascript
-static share(content, options)
+Share.share(content, options)
```
Open a dialog to share text content.
-In iOS, Returns a Promise which will be invoked an object containing `action`, `activityType`.
-If the user dismissed the dialog, the Promise will still be resolved with action being `Share.dismissedAction`
-and all the other keys being undefined.
+In iOS, Returns a Promise which will be invoked an object containing `action`, `activityType`. If the user dismissed the dialog, the Promise will still be resolved with action being `Share.dismissedAction` and all the other keys being undefined.
In Android, Returns a Promise which always be resolved with action being `Share.sharedAction`.
@@ -64,15 +62,12 @@ At least one of URL and message is required.
- `dialogTitle`
-
-
-
---
### `sharedAction()`
```javascript
-static sharedAction()
+Share.sharedAction()
```
@@ -86,12 +81,15 @@ The content was successfully shared.
### `dismissedAction()`
```javascript
-static dismissedAction()
+Share.dismissedAction()
```
The dialog has been dismissed.
-@platform ios
+
+| Platform |
+| - |
+| iOS |
diff --git a/docs/slider.md b/docs/slider.md
index 32f8eecdcf2d17..c3768149ccfa1a 100644
--- a/docs/slider.md
+++ b/docs/slider.md
@@ -17,7 +17,7 @@ the state of the root component (`App`). The same component
subscribes to the `onValueChange` of `Slider` and changes
the value using `setState`.
-```
+```javascript
import React from 'react';
import { StyleSheet, Text, View, Slider } from 'react-native';
@@ -67,7 +67,7 @@ const styles = StyleSheet.create({
### Props
-* [ViewPropTypes props...](docs/viewproptypes.html#props)
+- [View props...](docs/view-props.html)
- [`style`](docs/slider.html#style)
- [`disabled`](docs/slider.html#disabled)
- [`maximumValue`](docs/slider.html#maximumvalue)
@@ -103,7 +103,7 @@ Used to style and layout the `Slider`. See `StyleSheet.js` and
| Type | Required |
| - | - |
-| ViewPropTypes.style | No |
+| [ViewPropTypes.style](docs/viewproptypes.html#style) | No |
@@ -274,7 +274,7 @@ leftmost pixel of the image will be stretched to fill the track.
| Type | Required | Platform |
| - | - | - |
-| Image.propTypes.source | No | iOS |
+| [Image.propTypes.source](docs/image.html#source) | No | iOS |
@@ -289,7 +289,7 @@ rightmost pixel of the image will be stretched to fill the track.
| Type | Required | Platform |
| - | - | - |
-| Image.propTypes.source | No | iOS |
+| [Image.propTypes.source](docs/image.html#source) | No | iOS |
@@ -303,7 +303,7 @@ Sets an image for the thumb. Only static images are supported.
| Type | Required | Platform |
| - | - | - |
-| Image.propTypes.source | No | iOS |
+| [Image.propTypes.source](docs/image.html#source) | No | iOS |
@@ -318,7 +318,7 @@ The center pixel of the image will be stretched to fill the track.
| Type | Required | Platform |
| - | - | - |
-| Image.propTypes.source | No | iOS |
+| [Image.propTypes.source](docs/image.html#source) | No | iOS |
diff --git a/docs/snapshotviewios.md b/docs/snapshotviewios.md
index d11f73bb0fb8b4..7048f257a266db 100644
--- a/docs/snapshotviewios.md
+++ b/docs/snapshotviewios.md
@@ -7,9 +7,10 @@ permalink: docs/snapshotviewios.html
next: statusbar
previous: slider
---
+
### Props
-* [ViewPropTypes props...](docs/viewproptypes.html#props)
+- [View props...](docs/view-props.html)
- [`onSnapshotReady`](docs/snapshotviewios.html#onsnapshotready)
- [`testIdentifier`](docs/snapshotviewios.html#testidentifier)
diff --git a/docs/statusbar.md b/docs/statusbar.md
index ee78f4c85afaa3..e670011c7201df 100644
--- a/docs/statusbar.md
+++ b/docs/statusbar.md
@@ -35,15 +35,11 @@ mounted. One use case is to specify status bar styles per route using `Navigator
### Imperative API
-For cases where using a component is not ideal, there is also an imperative
-API exposed as static functions on the component. It is however not recommended
-to use the static API and the component for the same prop because any value
-set by the static API will get overriden by the one set by the component in
-the next render.
+For cases where using a component is not ideal, there is also an imperative API exposed as static functions on the component. It is however not recommended to use the static API and the component for the same prop because any value set by the static API will get overriden by the one set by the component in the next render.
### Constants
-`currentHeight` (Android only) The height of the status bar.
+`currentHeight` (Android only) The current height of the status bar on the device.
### Props
@@ -188,17 +184,17 @@ prop. Defaults to 'fade'.
### `setHidden()`
```javascript
-static setHidden(hidden: boolean, [animation]: StatusBarAnimation)
+StatusBar.setHidden(hidden: boolean, [animation]: StatusBarAnimation)
```
-Show or hide the status bar
+Show or hide the status bar.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
-| hidden | boolean | No | Hide the status bar. |
-| animation | [StatusBarAnimation](docs/statusbar.html#statusbaranimation) | Yes | Optional animation when changing the status bar hidden property. |
+| hidden | boolean | Yes | Hide the status bar. |
+| animation | [StatusBarAnimation](docs/statusbar.html#statusbaranimation) | No | Optional animation when changing the status bar hidden property. |
@@ -208,17 +204,17 @@ Show or hide the status bar
### `setBarStyle()`
```javascript
-static setBarStyle(style: StatusBarStyle, [animated]: boolean)
+StatusBar.setBarStyle(style: StatusBarStyle, [animated]: boolean)
```
-Set the status bar style
+Set the status bar style.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
-| style | [StatusBarStyle](docs/statusbar.html#statusbarstyle) | No | Status bar style to set |
-| animated | boolean | Yes | Animate the style change. |
+| style | [StatusBarStyle](docs/statusbar.html#statusbarstyle) | Yes | Status bar style to set |
+| animated | boolean | No | Animate the style change. |
@@ -228,16 +224,16 @@ Set the status bar style
### `setNetworkActivityIndicatorVisible()`
```javascript
-static setNetworkActivityIndicatorVisible(visible: boolean)
+StatusBar.setNetworkActivityIndicatorVisible(visible: boolean)
```
-Control the visibility of the network activity indicator
+Control the visibility of the network activity indicator.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
-| visible | boolean | No | Show the indicator. |
+| visible | boolean | Yes | Show the indicator. |
@@ -247,17 +243,17 @@ Control the visibility of the network activity indicator
### `setBackgroundColor()`
```javascript
-static setBackgroundColor(color: string, [animated]: boolean)
+StatusBar.setBackgroundColor(color: string, [animated]: boolean)
```
-Set the background color for the status bar
+Set the background color for the status bar.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
-| color | string | No | Background color. |
-| animated | boolean | Yes | Animate the style change. |
+| color | string | Yes | Background color. |
+| animated | boolean | No | Animate the style change. |
@@ -267,16 +263,16 @@ Set the background color for the status bar
### `setTranslucent()`
```javascript
-static setTranslucent(translucent: boolean)
+StatusBar.setTranslucent(translucent: boolean)
```
-Control the translucency of the status bar
+Control the translucency of the status bar.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
-| translucent | boolean | No | Set as translucent. |
+| translucent | boolean | Yes | Set as translucent. |
@@ -307,7 +303,7 @@ Status bar style
### StatusBarAnimation
-Status bar animation
+Status bar animation.
| Type |
| - |
diff --git a/docs/statusbarios.md b/docs/statusbarios.md
index 793f5f4f8db9fe..c0c6d2204bf48d 100644
--- a/docs/statusbarios.md
+++ b/docs/statusbarios.md
@@ -8,12 +8,4 @@ next: stylesheet
previous: share
---
-Use `StatusBar` for mutating the status bar.
-
-
-
-
----
-
-# Reference
-
+Use [`StatusBar`](docs/statusbar.html) for mutating the status bar.
diff --git a/docs/stylesheet.md b/docs/stylesheet.md
index 3d3ef03c45ad43..adf546b92ce1d8 100644
--- a/docs/stylesheet.md
+++ b/docs/stylesheet.md
@@ -54,8 +54,9 @@ subsequent uses are going to refer an id (not implemented yet).
### Methods
-- [`setStyleAttributePreprocessor`](docs/stylesheet.html#setstyleattributepreprocessor)
- [`create`](docs/stylesheet.html#create)
+- [`flatten`](docs/stylesheet.html#flatten)
+- [`setStyleAttributePreprocessor`](docs/stylesheet.html#setstyleattributepreprocessor)
### Properties
@@ -63,7 +64,6 @@ subsequent uses are going to refer an id (not implemented yet).
- [`hairlineWidth`](docs/stylesheet.html#hairlinewidth)
- [`absoluteFill`](docs/stylesheet.html#absolutefill)
- [`absoluteFillObject`](docs/stylesheet.html#absolutefillobject)
-- [`flatten`](docs/stylesheet.html#flatten)
@@ -74,51 +74,114 @@ subsequent uses are going to refer an id (not implemented yet).
## Methods
-### `setStyleAttributePreprocessor()`
+### `create()`
```javascript
-static setStyleAttributePreprocessor(property, process)
+StyleSheet.create(obj)
```
-WARNING: EXPERIMENTAL. Breaking changes will probably happen a lot and will
-not be reliably announced. The whole thing might be deleted, who knows? Use
-at your own risk.
+Creates a StyleSheet style reference from the given object.
-Sets a function to use to pre-process a style property value. This is used
-internally to process color and transform values. You should not use this
-unless you really know what you are doing and have exhausted other options.
+---
+### `flatten()`
+```javascript
+StyleSheet.flatten(styles)
+```
+Flattens an array of style objects, into one aggregated style object. Alternatively, this method can be used to lookup IDs, returned by StyleSheet.register.
----
+> **Note**:
+> Exercise caution as abusing this can tax you in terms of optimizations.
+>
+> IDs enable optimizations through the bridge and memory in general. Refering to style objects directly will deprive you of these optimizations.
-### `create()`
+Example:
```javascript
-static create(obj)
+const styles = StyleSheet.create({
+ listItem: {
+ flex: 1,
+ fontSize: 16,
+ color: 'white'
+ },
+ selectedListItem: {
+ color: 'green'
+ }
+});
+
+StyleSheet.flatten([styles.listItem, styles.selectedListItem])
+// returns { flex: 1, fontSize: 16, color: 'green' }
```
+Alternative use:
-Creates a StyleSheet style reference from the given object.
+```javascript
+StyleSheet.flatten(styles.listItem);
+// return { flex: 1, fontSize: 16, color: 'white' }
+// Simply styles.listItem would return its ID (number)
+```
+
+This method internally uses `StyleSheetRegistry.getStyleByID(style)` to resolve style objects represented by IDs. Thus, an array of style objects (instances of StyleSheet.create), are individually resolved to, their respective objects, merged as one and then returned. This also explains the alternative use.
+---
+
+### `setStyleAttributePreprocessor()`
+
+```javascript
+StyleSheet.setStyleAttributePreprocessor(property, process)
+```
+
+> WARNING: EXPERIMENTAL.
+> Breaking changes will probably happen a lot and will not be reliably announced. The whole thing might be deleted, who knows? Use at your own risk.
+
+Sets a function to use to pre-process a style property value. This is used internally to process color and transform values. You should not use this unless you really know what you are doing and have exhausted other options.
## Properties
+### `hairlineWidth`
+This is defined as the width of a thin line on the platform. It can be used as the thickness of a border or division between two elements.
----
+Example:
+
+```json
+{
+ borderBottomColor: '#bbb',
+ borderBottomWidth: StyleSheet.hairlineWidth
+}
+```
+This constant will always be a round number of pixels (so a line defined by it look crisp) and will try to match the standard width of a thin line on the underlying platform. However, you should not rely on it being a constant size, because on different platforms and screen densities its value may be calculated differently.
+A line with hairline width may not be visible if your simulator is downscaled.
---
+### `absoluteFill`
+
+A very common pattern is to create overlays with position absolute and zero positioning, so `absoluteFill` can be used for convenience and to reduce duplication of these repeated styles.
+
---
+### `absoluteFillObject`
+
+Sometimes you may want `absoluteFill` but with a couple tweaks - `absoluteFillObject` can be used to create a customized entry in a `StyleSheet`, e.g.:
+
+```javascript
+const styles = StyleSheet.create({
+ wrapper: {
+ ...StyleSheet.absoluteFillObject,
+ top: 10,
+ backgroundColor: 'transparent',
+ },
+});
+```
diff --git a/docs/switch.md b/docs/switch.md
index 6ce1a6f0204fe3..bac4b702f5aab5 100644
--- a/docs/switch.md
+++ b/docs/switch.md
@@ -9,17 +9,14 @@ previous: statusbar
---
Renders a boolean input.
-This is a controlled component that requires an `onValueChange` callback that
-updates the `value` prop in order for the component to reflect user actions.
-If the `value` prop is not updated, the component will continue to render
-the supplied `value` prop instead of the expected result of any user actions.
+This is a controlled component that requires an `onValueChange` callback that updates the `value` prop in order for the component to reflect user actions. If the `value` prop is not updated, the component will continue to render the supplied `value` prop instead of the expected result of any user actions.
@keyword checkbox
@keyword toggle
### Props
-* [ViewPropTypes props...](docs/viewproptypes.html#props)
+- [View props...](docs/view-props.html)
- [`disabled`](docs/switch.html#disabled)
- [`onTintColor`](docs/switch.html#ontintcolor)
- [`onValueChange`](docs/switch.html#onvaluechange)
@@ -30,9 +27,6 @@ the supplied `value` prop instead of the expected result of any user actions.
-
-
-
---
# Reference
diff --git a/docs/systrace.md b/docs/systrace.md
index 5e0cd57a6c1f56..30867f5943738a 100644
--- a/docs/systrace.md
+++ b/docs/systrace.md
@@ -164,12 +164,18 @@ static measureMethods(object, objectName, methodNames)
Measures multiple methods of a class. For example, you can do:
+
+```javascript
Systrace.measureMethods(JSON, 'JSON', ['parse', 'stringify']);
+```
-@param object
-@param objectName
-@param methodNames Map from method names to method display names.
+**Parameters:**
+| Name | Type | Required | Description |
+| - | - | - | - |
+| object | any | Yes | |
+| objectName | string | Yes | |
+| methodNames | array | Yes| Map from method names to method display names. |
@@ -183,12 +189,19 @@ static measure(objName, fnName, func)
Returns an profiled version of the input function. For example, you can:
+
+```javascript
JSON.parse = Systrace.measure('JSON', 'parse', JSON.parse);
+```
+
+**Parameters:**
+
+| Name | Type | Required | Description |
+| - | - | - | - |
+| objName | string | Yes | |
+| fnName | string | Yes | |
+| func | function | Yes | |
-@param objName
-@param fnName
-@param {function} func
-@return {function} replacement function
diff --git a/docs/tabbarios-item.md b/docs/tabbarios-item.md
index 687ebe1db154a4..981476b16485d1 100644
--- a/docs/tabbarios-item.md
+++ b/docs/tabbarios-item.md
@@ -7,9 +7,10 @@ permalink: docs/tabbarios-item.html
next: text
previous: tabbarios
---
+
### Props
-* [ViewPropTypes props...](docs/viewproptypes.html#props)
+- [ViewPropTypes props...](docs/viewproptypes.html#props)
- [`selected`](docs/tabbarios-item.html#selected)
- [`badge`](docs/tabbarios-item.html#badge)
- [`icon`](docs/tabbarios-item.html#icon)
@@ -53,7 +54,7 @@ Little red bubble that sits at the top right of the icon.
| Type | Required |
| - | - |
-| string, ,number | No |
+| string, number | No |
@@ -121,7 +122,7 @@ icon is defined. If left empty, the icon will be tinted in blue.
| Type | Required |
| - | - |
-| Image.propTypes.source | No |
+| [Image.propTypes.source](docs/image.html#source) | No |
@@ -134,7 +135,7 @@ React style object.
| Type | Required |
| - | - |
-| ViewPropTypes.style | No |
+| [ViewPropTypes.style](docs/viewproptypes.html#style) | No |
@@ -152,8 +153,6 @@ system ones.
| enum('bookmarks', 'contacts', 'downloads', 'favorites', 'featured', 'history', 'more', 'most-recent', 'most-viewed', 'recents', 'search', 'top-rated') | No |
-
-
---
### `title`
diff --git a/docs/tabbarios.md b/docs/tabbarios.md
index e8385e0a54dbaf..8c1d83a5321dc1 100644
--- a/docs/tabbarios.md
+++ b/docs/tabbarios.md
@@ -9,7 +9,7 @@ previous: switch
---
### Props
-* [ViewPropTypes props...](docs/viewproptypes.html#props)
+- [View props...](docs/view-props.html)
- [`barStyle`](docs/tabbarios.html#barstyle)
- [`barTintColor`](docs/tabbarios.html#bartintcolor)
- [`itemPositioning`](docs/tabbarios.html#itempositioning)
@@ -61,12 +61,10 @@ Background color of the tab bar
### `itemPositioning`
Specifies tab bar item positioning. Available values are:
-- fill - distributes items across the entire width of the tab bar
-- center - centers item in the available tab bar space
-- auto (default) - distributes items dynamically according to the
-user interface idiom. In a horizontally compact environment (e.g. iPhone 5)
-this value defaults to `fill`, in a horizontally regular one (e.g. iPad)
-it defaults to center.
+
+- `fill` - distributes items across the entire width of the tab bar
+- `center` - centers item in the available tab bar space
+- `auto` (default) - distributes items dynamically according to the user interface idiom. In a horizontally compact environment (e.g. iPhone 5) this value defaults to `fill`, in a horizontally regular one (e.g. iPad) it defaults to center.
| Type | Required |
| - | - |
@@ -83,7 +81,7 @@ it defaults to center.
| Type | Required |
| - | - |
-| ViewPropTypes.style | No |
+| [ViewPropTypes.style](docs/viewproptypes.html#style) | No |
diff --git a/docs/textstyleproptypes.md b/docs/text-style-props.md
similarity index 67%
rename from docs/textstyleproptypes.md
rename to docs/text-style-props.md
index c4f6def481bda1..72bf702655e0fb 100644
--- a/docs/textstyleproptypes.md
+++ b/docs/text-style-props.md
@@ -1,32 +1,32 @@
---
-id: textstyleproptypes
-title: TextStylePropTypes
+id: text-style-props
+title: Text Style Props
layout: docs
category: APIs
-permalink: docs/textstyleproptypes.html
-next: imagestyleproptypes
-previous: viewstyleproptypes
+permalink: docs/text-style-props.html
+next: image-style-props
+previous: view-style-props
---
### Props
-- [`textShadowOffset`](docs/textstyleproptypes.html#textshadowoffset)
-- [`color`](docs/textstyleproptypes.html#color)
-- [`fontSize`](docs/textstyleproptypes.html#fontsize)
-- [`fontStyle`](docs/textstyleproptypes.html#fontstyle)
-- [`fontWeight`](docs/textstyleproptypes.html#fontweight)
-- [`lineHeight`](docs/textstyleproptypes.html#lineheight)
-- [`textAlign`](docs/textstyleproptypes.html#textalign)
-- [`textDecorationLine`](docs/textstyleproptypes.html#textdecorationline)
-- [`textShadowColor`](docs/textstyleproptypes.html#textshadowcolor)
-- [`fontFamily`](docs/textstyleproptypes.html#fontfamily)
-- [`textShadowRadius`](docs/textstyleproptypes.html#textshadowradius)
-- [`includeFontPadding`](docs/textstyleproptypes.html#includefontpadding)
-- [`textAlignVertical`](docs/textstyleproptypes.html#textalignvertical)
-- [`fontVariant`](docs/textstyleproptypes.html#fontvariant)
-- [`letterSpacing`](docs/textstyleproptypes.html#letterspacing)
-- [`textDecorationColor`](docs/textstyleproptypes.html#textdecorationcolor)
-- [`textDecorationStyle`](docs/textstyleproptypes.html#textdecorationstyle)
-- [`writingDirection`](docs/textstyleproptypes.html#writingdirection)
+- [`textShadowOffset`](docs/text-style-props.html#textshadowoffset)
+- [`color`](docs/text-style-props.html#color)
+- [`fontSize`](docs/text-style-props.html#fontsize)
+- [`fontStyle`](docs/text-style-props.html#fontstyle)
+- [`fontWeight`](docs/text-style-props.html#fontweight)
+- [`lineHeight`](docs/text-style-props.html#lineheight)
+- [`textAlign`](docs/text-style-props.html#textalign)
+- [`textDecorationLine`](docs/text-style-props.html#textdecorationline)
+- [`textShadowColor`](docs/text-style-props.html#textshadowcolor)
+- [`fontFamily`](docs/text-style-props.html#fontfamily)
+- [`textShadowRadius`](docs/text-style-props.html#textshadowradius)
+- [`includeFontPadding`](docs/text-style-props.html#includefontpadding)
+- [`textAlignVertical`](docs/text-style-props.html#textalignvertical)
+- [`fontVariant`](docs/text-style-props.html#fontvariant)
+- [`letterSpacing`](docs/text-style-props.html#letterspacing)
+- [`textDecorationColor`](docs/text-style-props.html#textdecorationcolor)
+- [`textDecorationStyle`](docs/text-style-props.html#textdecorationstyle)
+- [`writingDirection`](docs/text-style-props.html#writingdirection)
diff --git a/docs/text.md b/docs/text.md
index 2f43c52ede2cd9..b64199adea98d4 100644
--- a/docs/text.md
+++ b/docs/text.md
@@ -7,6 +7,7 @@ permalink: docs/text.html
next: textinput
previous: tabbarios-item
---
+
A React component for displaying text.
`Text` supports nesting, styling, and touch handling.
diff --git a/docs/textinput.md b/docs/textinput.md
index 75ad2ca91c2ced..e032d386c703bb 100644
--- a/docs/textinput.md
+++ b/docs/textinput.md
@@ -118,7 +118,7 @@ or control this param programmatically with native code.
### Props
-* [ViewPropTypes props...](docs/viewproptypes.html#props)
+- [View props...](docs/view-props.html)
- [`placeholderTextColor`](docs/textinput.html#placeholdertextcolor)
- [`allowFontScaling`](docs/textinput.html#allowfontscaling)
- [`autoCorrect`](docs/textinput.html#autocorrect)
diff --git a/docs/timepickerandroid.md b/docs/timepickerandroid.md
index 570dfc1566e363..24e877aa8e2506 100644
--- a/docs/timepickerandroid.md
+++ b/docs/timepickerandroid.md
@@ -46,7 +46,7 @@ try {
### `open()`
```javascript
-static open(options)
+TimePickerAndroid.open(options)
```
@@ -76,7 +76,7 @@ being undefined. **Always** check whether the `action` before reading the values
### `timeSetAction()`
```javascript
-static timeSetAction()
+TimePickerAndroid.timeSetAction()
```
@@ -90,7 +90,7 @@ A time has been selected.
### `dismissedAction()`
```javascript
-static dismissedAction()
+TimePickerAndroid.dismissedAction()
```
diff --git a/docs/toastandroid.md b/docs/toastandroid.md
index a8408b17e98559..ecb15135bf148d 100644
--- a/docs/toastandroid.md
+++ b/docs/toastandroid.md
@@ -21,6 +21,7 @@ The 'showWithGravityAndOffset' function adds on the ability to specify offset
These offset values will translate to pixels.
Basic usage:
+
```javascript
ToastAndroid.show('A pikachu appeared nearby !', ToastAndroid.SHORT);
ToastAndroid.showWithGravity('All Your Base Are Belong To Us', ToastAndroid.SHORT, ToastAndroid.CENTER);
@@ -55,7 +56,7 @@ ToastAndroid.showWithGravityAndOffset('A wild toast appeared!', ToastAndroid.LON
### `show()`
```javascript
-static show(message, duration)
+ToastAndroid.show(message, duration)
```
@@ -65,7 +66,7 @@ static show(message, duration)
### `showWithGravity()`
```javascript
-static showWithGravity(message, duration, gravity)
+ToastAndroid.showWithGravity(message, duration, gravity)
```
@@ -75,28 +76,30 @@ static showWithGravity(message, duration, gravity)
### `showWithGravityAndOffset()`
```javascript
-static showWithGravityAndOffset(message, duration, gravity, xOffset, yOffset)
+ToastAndroid.showWithGravityAndOffset(message, duration, gravity, xOffset, yOffset)
```
## Properties
-
+### `SHORT`
---
-
+### `LONG`
---
-
+### `TOP`
---
+### `BOTTOM`
---
+### `CENTER`
diff --git a/docs/toolbarandroid.md b/docs/toolbarandroid.md
index 17bdc46c6e75fa..ba37cb65c903e9 100644
--- a/docs/toolbarandroid.md
+++ b/docs/toolbarandroid.md
@@ -43,7 +43,7 @@ onActionSelected: function(position) {
### Props
-* [ViewPropTypes props...](docs/viewproptypes.html#props)
+- [View props...](docs/view-props.html)
- [`overflowIcon`](docs/toolbarandroid.html#overflowicon)
- [`actions`](docs/toolbarandroid.html#actions)
- [`contentInsetStart`](docs/toolbarandroid.html#contentinsetstart)
diff --git a/docs/touchablehighlight.md b/docs/touchablehighlight.md
index cbaaf3222d27b9..2842c41a2f3282 100644
--- a/docs/touchablehighlight.md
+++ b/docs/touchablehighlight.md
@@ -169,7 +169,7 @@ Called immediately after the underlay is shown
| Type | Required |
| - | - |
-| ViewPropTypes.style | No |
+| [ViewPropTypes.style](docs/viewproptypes.html#style) | No |
diff --git a/docs/touchablenativefeedback.md b/docs/touchablenativefeedback.md
index 1e21ad203017be..a821eebeb31b06 100644
--- a/docs/touchablenativefeedback.md
+++ b/docs/touchablenativefeedback.md
@@ -99,11 +99,10 @@ fallback to background.
### `SelectableBackground()`
```javascript
-static SelectableBackground()
+TouchableNativeFeedback.SelectableBackground()
```
-Creates an object that represents android theme's default background for
-selectable elements (?android:attr/selectableItemBackground).
+Creates an object that represents android theme's default background for selectable elements (?android:attr/selectableItemBackground).
@@ -112,11 +111,10 @@ selectable elements (?android:attr/selectableItemBackground).
### `SelectableBackgroundBorderless()`
```javascript
-static SelectableBackgroundBorderless()
+TouchableNativeFeedback.SelectableBackgroundBorderless()
```
-Creates an object that represent android theme's default background for borderless
-selectable elements (?android:attr/selectableItemBackgroundBorderless).
+Creates an object that represent android theme's default background for borderless selectable elements (?android:attr/selectableItemBackgroundBorderless).
Available on android API level 21+.
@@ -126,21 +124,17 @@ Available on android API level 21+.
### `Ripple()`
```javascript
-static Ripple(color: string, borderless: boolean)
+TouchableNativeFeedback.Ripple(color: string, borderless: boolean)
```
-Creates an object that represents ripple drawable with specified color (as a
-string). If property `borderless` evaluates to true the ripple will
-render outside of the view bounds (see native actionbar buttons as an
-example of that behavior). This background type is available on Android
-API level 21+.
+Creates an object that represents ripple drawable with specified color (as a string). If property `borderless` evaluates to true the ripple will render outside of the view bounds (see native actionbar buttons as an example of that behavior). This background type is available on Android API level 21+.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
-| color | string | No | The ripple color |
-| borderless | boolean | No | If the ripple can render outside it's bounds |
+| color | string | Yes | The ripple color |
+| borderless | boolean | Yes | If the ripple can render outside its bounds |
@@ -150,8 +144,8 @@ API level 21+.
### `canUseNativeForeground()`
```javascript
-static canUseNativeForeground()
+TouchableNativeFeedback.canUseNativeForeground()
```
-
+Whether native foreground ripple is available on the current version of Android.
diff --git a/docs/touchablewithoutfeedback.md b/docs/touchablewithoutfeedback.md
index 6ac830f1ffdf02..e352798d791378 100644
--- a/docs/touchablewithoutfeedback.md
+++ b/docs/touchablewithoutfeedback.md
@@ -48,12 +48,10 @@ If you wish to have several child components, wrap them in a View.
### `hitSlop`
-This defines how far your touch can start away from the button. This is
-added to `pressRetentionOffset` when moving off of the button.
-** NOTE **
-The touch area never extends past the parent view bounds and the Z-index
-of sibling views always takes precedence if a touch hits two overlapping
-views.
+This defines how far your touch can start away from the button. This is added to `pressRetentionOffset` when moving off of the button.
+
+> Note:
+> The touch area never extends past the parent view bounds and the Z-index of sibling views always takes precedence if a touch hits two overlapping views.
| Type | Required |
| - | - |
diff --git a/docs/vibration.md b/docs/vibration.md
index c19e27c2d9e380..ca49bab23ac532 100644
--- a/docs/vibration.md
+++ b/docs/vibration.md
@@ -63,7 +63,7 @@ Vibration.cancel()
### `vibrate()`
```javascript
-static vibrate(pattern: number, Array, repeat: boolean)
+Vibration.vibrate(pattern: number, Array, repeat: boolean)
```
Trigger a vibration with specified `pattern`.
@@ -72,8 +72,8 @@ Trigger a vibration with specified `pattern`.
| Name | Type | Required | Description |
| - | - | - | - |
-| pattern | number,Array | No | Vibration pattern, accept a number or an array of number. Default to 400ms. |
-| repeat | boolean | No | Optional. Repeat vibration pattern until cancel(), default to false. |
+| pattern | number, Array | Yes | Vibration pattern, accept a number or an array of number. Default to 400ms. |
+| repeat | boolean | Yes | Optional. Repeat vibration pattern until cancel(), default to false. |
@@ -83,13 +83,11 @@ Trigger a vibration with specified `pattern`.
### `cancel()`
```javascript
-static cancel()
-```
-
-Stop vibration
-```
Vibration.cancel()
```
+Stop vibration.
+
+
diff --git a/docs/vibrationios.md b/docs/vibrationios.md
index ba4a175a67e64d..e2452907caaabd 100644
--- a/docs/vibrationios.md
+++ b/docs/vibrationios.md
@@ -8,18 +8,15 @@ next: layout-props
previous: vibration
---
-NOTE: `VibrationIOS` is being deprecated. Use `Vibration` instead.
+> NOTE:
+> `VibrationIOS` is deprecated. Use [`Vibration`](docs/vibration.html) instead.
-The Vibration API is exposed at `VibrationIOS.vibrate()`. On iOS, calling this
-function will trigger a one second vibration. The vibration is asynchronous
-so this method will return immediately.
+The Vibration API is exposed at `VibrationIOS.vibrate()`. On iOS, calling this function will trigger a one second vibration. The vibration is asynchronous so this method will return immediately.
-There will be no effect on devices that do not support Vibration, eg. the iOS
-simulator.
+There will be no effect on devices that do not support Vibration, eg. the iOS simulator.
Vibration patterns are currently unsupported.
-
### Methods
- [`vibrate`](docs/vibrationios.html#vibrate)
@@ -36,11 +33,10 @@ Vibration patterns are currently unsupported.
### `vibrate()`
```javascript
-static vibrate()
+VibrationIOS.vibrate()
```
-
-@deprecated
+**Deprecated.**
diff --git a/docs/viewproptypes.md b/docs/view-props.md
similarity index 86%
rename from docs/viewproptypes.md
rename to docs/view-props.md
index 304ebc34a7c84c..3ab3c2b3cd1c4e 100644
--- a/docs/viewproptypes.md
+++ b/docs/view-props.md
@@ -1,44 +1,44 @@
---
-id: viewproptypes
-title: ViewPropTypes
+id: view-props
+title: View Props
layout: docs
category: APIs
-permalink: docs/viewproptypes.html
-next: viewstyleproptypes
+permalink: docs/view-props.html
+next: view-style-props
previous: shadow-props
---
### Props
-- [`onStartShouldSetResponder`](docs/viewproptypes.html#onstartshouldsetresponder)
-- [`accessibilityLabel`](docs/viewproptypes.html#accessibilitylabel)
-- [`hitSlop`](docs/viewproptypes.html#hitslop)
-- [`nativeID`](docs/viewproptypes.html#nativeid)
-- [`onAccessibilityTap`](docs/viewproptypes.html#onaccessibilitytap)
-- [`onLayout`](docs/viewproptypes.html#onlayout)
-- [`onMagicTap`](docs/viewproptypes.html#onmagictap)
-- [`onMoveShouldSetResponder`](docs/viewproptypes.html#onmoveshouldsetresponder)
-- [`onMoveShouldSetResponderCapture`](docs/viewproptypes.html#onmoveshouldsetrespondercapture)
-- [`onResponderGrant`](docs/viewproptypes.html#onrespondergrant)
-- [`onResponderMove`](docs/viewproptypes.html#onrespondermove)
-- [`onResponderReject`](docs/viewproptypes.html#onresponderreject)
-- [`onResponderRelease`](docs/viewproptypes.html#onresponderrelease)
-- [`onResponderTerminate`](docs/viewproptypes.html#onresponderterminate)
-- [`onResponderTerminationRequest`](docs/viewproptypes.html#onresponderterminationrequest)
-- [`accessible`](docs/viewproptypes.html#accessible)
-- [`onStartShouldSetResponderCapture`](docs/viewproptypes.html#onstartshouldsetrespondercapture)
-- [`pointerEvents`](docs/viewproptypes.html#pointerevents)
-- [`removeClippedSubviews`](docs/viewproptypes.html#removeclippedsubviews)
-- [`style`](docs/viewproptypes.html#style)
-- [`testID`](docs/viewproptypes.html#testid)
-- [`accessibilityComponentType`](docs/viewproptypes.html#accessibilitycomponenttype)
-- [`accessibilityLiveRegion`](docs/viewproptypes.html#accessibilityliveregion)
-- [`collapsable`](docs/viewproptypes.html#collapsable)
-- [`importantForAccessibility`](docs/viewproptypes.html#importantforaccessibility)
-- [`needsOffscreenAlphaCompositing`](docs/viewproptypes.html#needsoffscreenalphacompositing)
-- [`renderToHardwareTextureAndroid`](docs/viewproptypes.html#rendertohardwaretextureandroid)
-- [`accessibilityTraits`](docs/viewproptypes.html#accessibilitytraits)
-- [`accessibilityViewIsModal`](docs/viewproptypes.html#accessibilityviewismodal)
-- [`shouldRasterizeIOS`](docs/viewproptypes.html#shouldrasterizeios)
+- [`onStartShouldSetResponder`](docs/view-props.html#onstartshouldsetresponder)
+- [`accessibilityLabel`](docs/view-props.html#accessibilitylabel)
+- [`hitSlop`](docs/view-props.html#hitslop)
+- [`nativeID`](docs/view-props.html#nativeid)
+- [`onAccessibilityTap`](docs/view-props.html#onaccessibilitytap)
+- [`onLayout`](docs/view-props.html#onlayout)
+- [`onMagicTap`](docs/view-props.html#onmagictap)
+- [`onMoveShouldSetResponder`](docs/view-props.html#onmoveshouldsetresponder)
+- [`onMoveShouldSetResponderCapture`](docs/view-props.html#onmoveshouldsetrespondercapture)
+- [`onResponderGrant`](docs/view-props.html#onrespondergrant)
+- [`onResponderMove`](docs/view-props.html#onrespondermove)
+- [`onResponderReject`](docs/view-props.html#onresponderreject)
+- [`onResponderRelease`](docs/view-props.html#onresponderrelease)
+- [`onResponderTerminate`](docs/view-props.html#onresponderterminate)
+- [`onResponderTerminationRequest`](docs/view-props.html#onresponderterminationrequest)
+- [`accessible`](docs/view-props.html#accessible)
+- [`onStartShouldSetResponderCapture`](docs/view-props.html#onstartshouldsetrespondercapture)
+- [`pointerEvents`](docs/view-props.html#pointerevents)
+- [`removeClippedSubviews`](docs/view-props.html#removeclippedsubviews)
+- [`style`](docs/view-props.html#style)
+- [`testID`](docs/view-props.html#testid)
+- [`accessibilityComponentType`](docs/view-props.html#accessibilitycomponenttype)
+- [`accessibilityLiveRegion`](docs/view-props.html#accessibilityliveregion)
+- [`collapsable`](docs/view-props.html#collapsable)
+- [`importantForAccessibility`](docs/view-props.html#importantforaccessibility)
+- [`needsOffscreenAlphaCompositing`](docs/view-props.html#needsoffscreenalphacompositing)
+- [`renderToHardwareTextureAndroid`](docs/view-props.html#rendertohardwaretextureandroid)
+- [`accessibilityTraits`](docs/view-props.html#accessibilitytraits)
+- [`accessibilityViewIsModal`](docs/view-props.html#accessibilityviewismodal)
+- [`shouldRasterizeIOS`](docs/view-props.html#shouldrasterizeios)
@@ -399,7 +399,7 @@ subviews must also have `overflow: hidden`, as should the containing view
| Type | Required |
| - | - |
-| stylePropType | No |
+| style | No |
diff --git a/docs/viewstyleproptypes.md b/docs/view-style-props.md
similarity index 58%
rename from docs/viewstyleproptypes.md
rename to docs/view-style-props.md
index 08bd57386e8035..b369582d5c4960 100644
--- a/docs/viewstyleproptypes.md
+++ b/docs/view-style-props.md
@@ -1,40 +1,40 @@
---
-id: viewstyleproptypes
-title: ViewStylePropTypes
+id: view-style-props
+title: View Style Props
layout: docs
category: APIs
-permalink: docs/viewstyleproptypes.html
-next: textstyleproptypes
-previous: viewproptypes
+permalink: docs/view-style-props.html
+next: text-style-props
+previous: view-props
---
### Props
-- [`borderRightColor`](docs/viewstyleproptypes.html#borderrightcolor)
-- [`backfaceVisibility`](docs/viewstyleproptypes.html#backfacevisibility)
-- [`borderBottomColor`](docs/viewstyleproptypes.html#borderbottomcolor)
-- [`borderBottomEndRadius`](docs/viewstyleproptypes.html#borderbottomendradius)
-- [`borderBottomLeftRadius`](docs/viewstyleproptypes.html#borderbottomleftradius)
-- [`borderBottomRightRadius`](docs/viewstyleproptypes.html#borderbottomrightradius)
-- [`borderBottomStartRadius`](docs/viewstyleproptypes.html#borderbottomstartradius)
-- [`borderBottomWidth`](docs/viewstyleproptypes.html#borderbottomwidth)
-- [`borderColor`](docs/viewstyleproptypes.html#bordercolor)
-- [`borderEndColor`](docs/viewstyleproptypes.html#borderendcolor)
-- [`borderLeftColor`](docs/viewstyleproptypes.html#borderleftcolor)
-- [`borderLeftWidth`](docs/viewstyleproptypes.html#borderleftwidth)
-- [`borderRadius`](docs/viewstyleproptypes.html#borderradius)
-- [`backgroundColor`](docs/viewstyleproptypes.html#backgroundcolor)
-- [`borderRightWidth`](docs/viewstyleproptypes.html#borderrightwidth)
-- [`borderStartColor`](docs/viewstyleproptypes.html#borderstartcolor)
-- [`borderStyle`](docs/viewstyleproptypes.html#borderstyle)
-- [`borderTopColor`](docs/viewstyleproptypes.html#bordertopcolor)
-- [`borderTopEndRadius`](docs/viewstyleproptypes.html#bordertopendradius)
-- [`borderTopLeftRadius`](docs/viewstyleproptypes.html#bordertopleftradius)
-- [`borderTopRightRadius`](docs/viewstyleproptypes.html#bordertoprightradius)
-- [`borderTopStartRadius`](docs/viewstyleproptypes.html#bordertopstartradius)
-- [`borderTopWidth`](docs/viewstyleproptypes.html#bordertopwidth)
-- [`borderWidth`](docs/viewstyleproptypes.html#borderwidth)
-- [`opacity`](docs/viewstyleproptypes.html#opacity)
-- [`elevation`](docs/viewstyleproptypes.html#elevation)
+- [`borderRightColor`](docs/view-style-props.html#borderrightcolor)
+- [`backfaceVisibility`](docs/view-style-props.html#backfacevisibility)
+- [`borderBottomColor`](docs/view-style-props.html#borderbottomcolor)
+- [`borderBottomEndRadius`](docs/view-style-props.html#borderbottomendradius)
+- [`borderBottomLeftRadius`](docs/view-style-props.html#borderbottomleftradius)
+- [`borderBottomRightRadius`](docs/view-style-props.html#borderbottomrightradius)
+- [`borderBottomStartRadius`](docs/view-style-props.html#borderbottomstartradius)
+- [`borderBottomWidth`](docs/view-style-props.html#borderbottomwidth)
+- [`borderColor`](docs/view-style-props.html#bordercolor)
+- [`borderEndColor`](docs/view-style-props.html#borderendcolor)
+- [`borderLeftColor`](docs/view-style-props.html#borderleftcolor)
+- [`borderLeftWidth`](docs/view-style-props.html#borderleftwidth)
+- [`borderRadius`](docs/view-style-props.html#borderradius)
+- [`backgroundColor`](docs/view-style-props.html#backgroundcolor)
+- [`borderRightWidth`](docs/view-style-props.html#borderrightwidth)
+- [`borderStartColor`](docs/view-style-props.html#borderstartcolor)
+- [`borderStyle`](docs/view-style-props.html#borderstyle)
+- [`borderTopColor`](docs/view-style-props.html#bordertopcolor)
+- [`borderTopEndRadius`](docs/view-style-props.html#bordertopendradius)
+- [`borderTopLeftRadius`](docs/view-style-props.html#bordertopleftradius)
+- [`borderTopRightRadius`](docs/view-style-props.html#bordertoprightradius)
+- [`borderTopStartRadius`](docs/view-style-props.html#bordertopstartradius)
+- [`borderTopWidth`](docs/view-style-props.html#bordertopwidth)
+- [`borderWidth`](docs/view-style-props.html#borderwidth)
+- [`opacity`](docs/view-style-props.html#opacity)
+- [`elevation`](docs/view-style-props.html#elevation)
diff --git a/docs/view.md b/docs/view.md
index f381c132b1836e..c00b327a440a68 100644
--- a/docs/view.md
+++ b/docs/view.md
@@ -7,17 +7,12 @@ permalink: docs/view.html
next: viewpagerandroid
previous: touchablewithoutfeedback
---
-The most fundamental component for building a UI, `View` is a container that supports layout with
-[flexbox](docs/flexbox.html), [style](docs/style.html),
-[some touch handling](docs/handling-touches.html), and
-[accessibility](docs/accessibility.html) controls. `View` maps directly to the
-native view equivalent on whatever platform React Native is running on, whether that is a
-`UIView`, `
`, `android.view`, etc.
+
+The most fundamental component for building a UI, `View` is a container that supports layout with [flexbox](docs/flexbox.html), [style](docs/style.html), [some touch handling](docs/handling-touches.html), and [accessibility](docs/accessibility.html) controls. `View` maps directly to the native view equivalent on whatever platform React Native is running on, whether that is a `UIView`, `
`, `android.view`, etc.
`View` is designed to be nested inside other views and can have 0 to many children of any type.
-This example creates a `View` that wraps two colored boxes and a text component in a row with
-padding.
+This example creates a `View` that wraps two colored boxes and a text component in a row with padding.
```javascript
class ViewColoredBoxesWithText extends Component {
@@ -33,13 +28,11 @@ class ViewColoredBoxesWithText extends Component {
}
```
-> `View`s are designed to be used with [`StyleSheet`](docs/style.html) for clarity
-> and performance, although inline styles are also supported.
+> `View`s are designed to be used with [`StyleSheet`](docs/style.html) for clarity and performance, although inline styles are also supported.
### Synthetic Touch Events
-For `View` responder props (e.g., `onResponderMove`), the synthetic touch event passed to them
-are of the following form:
+For `View` responder props (e.g., `onResponderMove`), the synthetic touch event passed to them are of the following form:
- `nativeEvent`
- `changedTouches` - Array of all touch events that have changed since the last event.
@@ -54,7 +47,7 @@ are of the following form:
### Props
-* [ViewPropTypes props...](docs/viewproptypes.html#props)
+- [View props...](docs/view-props.html)
- [`onStartShouldSetResponder`](docs/view.html#onstartshouldsetresponder)
- [`accessibilityLabel`](docs/view.html#accessibilitylabel)
- [`hitSlop`](docs/view.html#hitslop)
diff --git a/docs/viewpagerandroid.md b/docs/viewpagerandroid.md
index 0288ea25b6a6f2..8b4006445f33db 100644
--- a/docs/viewpagerandroid.md
+++ b/docs/viewpagerandroid.md
@@ -49,7 +49,7 @@ var styles = {
### Props
-* [ViewPropTypes props...](docs/viewproptypes.html#props)
+- [View props...](docs/view-props.html)
- [`initialPage`](docs/viewpagerandroid.html#initialpage)
- [`keyboardDismissMode`](docs/viewpagerandroid.html#keyboarddismissmode)
- [`onPageScroll`](docs/viewpagerandroid.html#onpagescroll)
@@ -92,8 +92,9 @@ update the page, and `onPageSelected` to monitor page changes
### `keyboardDismissMode`
Determines whether the keyboard gets dismissed in response to a drag.
- - 'none' (the default), drags do not dismiss the keyboard.
- - 'on-drag', the keyboard is dismissed when a drag begins.
+
+- 'none' (the default), drags do not dismiss the keyboard.
+- 'on-drag', the keyboard is dismissed when a drag begins.
| Type | Required |
| - | - |
@@ -106,13 +107,11 @@ Determines whether the keyboard gets dismissed in response to a drag.
### `onPageScroll`
-Executed when transitioning between pages (ether because of animation for
-the requested page change or when user is swiping/dragging between pages)
-The `event.nativeEvent` object for this callback will carry following data:
- - position - index of first page from the left that is currently visible
- - offset - value from range [0,1) describing stage between page transitions.
- Value x means that (1 - x) fraction of the page at "position" index is
- visible, and x fraction of the next page is visible.
+Executed when transitioning between pages (ether because of animation for the requested page change or when user is swiping/dragging between pages) The `event.nativeEvent` object for this callback will carry following data:
+
+- position - index of first page from the left that is currently visible
+- offset - value from range [0,1) describing stage between page transitions.
+ Value x means that (1 - x) fraction of the page at "position" index is visible, and x fraction of the next page is visible.
| Type | Required |
| - | - |
diff --git a/docs/virtualizedlist.md b/docs/virtualizedlist.md
index 6d4054ba18c76b..016eee879545ff 100644
--- a/docs/virtualizedlist.md
+++ b/docs/virtualizedlist.md
@@ -7,48 +7,59 @@ permalink: docs/virtualizedlist.html
next: webview
previous: viewpagerandroid
---
-Base implementation for the more convenient [``](/react-native/docs/flatlist.html)
-and [``](/react-native/docs/sectionlist.html) components, which are also better
-documented. In general, this should only really be used if you need more flexibility than
-`FlatList` provides, e.g. for use with immutable data instead of plain arrays.
-Virtualization massively improves memory consumption and performance of large lists by
-maintaining a finite render window of active items and replacing all items outside of the render
-window with appropriately sized blank space. The window adapts to scrolling behavior, and items
-are rendered incrementally with low-pri (after any running interactions) if they are far from the
-visible area, or with hi-pri otherwise to minimize the potential of seeing blank space.
+Base implementation for the more convenient [``](/react-native/docs/flatlist.html) and [``](/react-native/docs/sectionlist.html) components, which are also better documented. In general, this should only really be used if you need more flexibility than `FlatList` provides, e.g. for use with immutable data instead of plain arrays.
+
+Virtualization massively improves memory consumption and performance of large lists by maintaining a finite render window of active items and replacing all items outside of the render window with appropriately sized blank space. The window adapts to scrolling behavior, and items are rendered incrementally with low-pri (after any running interactions) if they are far from the visible area, or with hi-pri otherwise to minimize the potential of seeing blank space.
Some caveats:
-- Internal state is not preserved when content scrolls out of the render window. Make sure all
- your data is captured in the item data or external stores like Flux, Redux, or Relay.
-- This is a `PureComponent` which means that it will not re-render if `props` remain shallow-
- equal. Make sure that everything your `renderItem` function depends on is passed as a prop
- (e.g. `extraData`) that is not `===` after updates, otherwise your UI may not update on
- changes. This includes the `data` prop and parent component state.
-- In order to constrain memory and enable smooth scrolling, content is rendered asynchronously
- offscreen. This means it's possible to scroll faster than the fill rate ands momentarily see
- blank content. This is a tradeoff that can be adjusted to suit the needs of each application,
- and we are working on improving it behind the scenes.
-- By default, the list looks for a `key` prop on each item and uses that for the React key.
- Alternatively, you can provide a custom `keyExtractor` prop.
+- Internal state is not preserved when content scrolls out of the render window. Make sure all your data is captured in the item data or external stores like Flux, Redux, or Relay.
+- This is a `PureComponent` which means that it will not re-render if `props` remain shallow-equal. Make sure that everything your `renderItem` function depends on is passed as a prop (e.g. `extraData`) that is not `===` after updates, otherwise your UI may not update on changes. This includes the `data` prop and parent component state.
+- In order to constrain memory and enable smooth scrolling, content is rendered asynchronously offscreen. This means it's possible to scroll faster than the fill rate ands momentarily see blank content. This is a tradeoff that can be adjusted to suit the needs of each application, and we are working on improving it behind the scenes.
+- By default, the list looks for a `key` prop on each item and uses that for the React key. Alternatively, you can provide a custom `keyExtractor` prop.
### Props
-- [`last`](docs/virtualizedlist.html#last)
-- [`first`](docs/virtualizedlist.html#first)
+- [`ScrollView` props...](docs/scrollview.html#props)
+- [`renderItem`](docs/virtualizedlist.html#renderitem)
+- [`data`](docs/virtualizedlist.html#data)
+- [`getItem`](docs/virtualizedlist.html#getitem)
+- [`getItemCount`](docs/virtualizedlist.html#getitemcount)
+- [`debug`](docs/virtualizedlist.html#debug)
+- [`extraData`](docs/virtualizedlist.html#extradata)
+- [`getItemLayout`](docs/virtualizedlist.html#getitemlayout)
+- [`initialScrollIndex`](docs/virtualizedlist.html#initialscrollindex)
+- [`inverted`](docs/virtualizedlist.html#inverted)
+- [`CellRendererComponent`](docs/virtualizedlist.html#cellrenderercomponent)
+- [`ListEmptyComponent`](docs/virtualizedlist.html#listemptycomponent)
+- [`ListFooterComponent`](docs/virtualizedlist.html#listfootercomponent)
+- [`ListHeaderComponent`](docs/virtualizedlist.html#listheadercomponent)
+- [`onEndReached`](docs/virtualizedlist.html#onendreached)
+- [`onLayout`](docs/virtualizedlist.html#onlayout)
+- [`onRefresh`](docs/virtualizedlist.html#onrefresh)
+- [`onScrollToIndexFailed`](docs/virtualizedlist.html#onscrolltoindexfailed)
+- [`onViewableItemsChanged`](docs/virtualizedlist.html#onviewableitemschanged)
+- [`refreshing`](docs/virtualizedlist.html#refreshing)
+- [`removeClippedSubviews`](docs/virtualizedlist.html#removeclippedsubviews)
+- [`renderScrollComponent`](docs/virtualizedlist.html#renderscrollcomponent)
+- [`viewabilityConfig`](docs/virtualizedlist.html#viewabilityconfig)
+- [`viewabilityConfigCallbackPairs`](docs/virtualizedlist.html#viewabilityconfigcallbackpairs)
- [`horizontal`](docs/virtualizedlist.html#horizontal)
- [`initialNumToRender`](docs/virtualizedlist.html#initialnumtorender)
- [`keyExtractor`](docs/virtualizedlist.html#keyextractor)
-- [`disableVirtualization`](docs/virtualizedlist.html#disablevirtualization)
- [`maxToRenderPerBatch`](docs/virtualizedlist.html#maxtorenderperbatch)
- [`onEndReachedThreshold`](docs/virtualizedlist.html#onendreachedthreshold)
- [`scrollEventThrottle`](docs/virtualizedlist.html#scrolleventthrottle)
- [`updateCellsBatchingPeriod`](docs/virtualizedlist.html#updatecellsbatchingperiod)
- [`windowSize`](docs/virtualizedlist.html#windowsize)
+- [`disableVirtualization`](docs/virtualizedlist.html#disablevirtualization)
+- [`progressViewOffset`](docs/virtualizedlist.html#progressviewoffset)
+### State
-
+- [`first`](docs/virtualizedlist.html#first)
+- [`last`](docs/virtualizedlist.html#last)
### Methods
@@ -74,104 +85,384 @@ Some caveats:
## Props
-### `last`
+### `renderItem`
+
+| Type | Required |
+| - | - |
+| number | Yes |
+
+
+---
+### `data`
+
+The default accessor functions assume this is an array of objects with shape `{key: string}` but you can override `getItem`, `getItemCount`, and `keyExtractor` to handle any type of index-based data.
| Type | Required |
| - | - |
-| number | Yes |
+| any | Yes |
+
+
+---
+
+
+### `getItem`
+
+```javascript
+(data: any, index: number) => object
+```
+A generic accessor for extracting an item from any sort of data blob.
+| Type | Required |
+| - | - |
+| function | Yes |
---
-### `first`
+### `getItemCount`
+
+```javascript
+(data: any) => number
+```
+Determines how many items are in the data blob.
| Type | Required |
| - | - |
-| number | Yes |
+| function | Yes |
+
+
+---
+### `debug`
+
+`debug` will turn on extra logging and visual overlays to aid with debugging both usage and implementation, but with a significant perf hit.
+
+| Type | Required |
+| - | - |
+| boolean | No |
+
---
-### `horizontal`
+### `extraData`
+A marker property for telling the list to re-render (since it implements `PureComponent`). If any of your `renderItem`, Header, Footer, etc. functions depend on anything outside of the `data` prop, stick it here and treat it immutably.
| Type | Required |
| - | - |
-| | No |
+| any | No |
+
+
+---
+
+
+### `getItemLayout`
+```javascript
+(
+ data: any,
+ index: number,
+ ) => {length: number, offset: number, index: number}
+```
+| Type | Required |
+| - | - |
+| function | No |
---
-### `initialNumToRender`
+### `initialScrollIndex`
+Instead of starting at the top with the first item, start at `initialScrollIndex`. This disables the "scroll to top" optimization that keeps the first `initialNumToRender` items always rendered and immediately renders the items starting at this initial index. Requires `getItemLayout` to be implemented.
| Type | Required |
| - | - |
-| | No |
+| number | No |
+
+
+---
+
+### `inverted`
+Reverses the direction of scroll. Uses scale transforms of -1.
+
+| Type | Required |
+| - | - |
+| boolean | No |
---
-### `keyExtractor`
+### `CellRendererComponent`
+Each cell is rendered using this element. Can be a React Component Class,or a render function. Defaults to using [`View`](docs/view.html).
| Type | Required |
| - | - |
-| | No |
+| component, function | No |
+
+---
+
+
+### `ListEmptyComponent`
+
+Rendered when the list is empty. Can be a React Component Class, a render function, or a rendered element.
+| Type | Required |
+| - | - |
+| component, function, element | No |
---
-### `disableVirtualization`
+### `ListFooterComponent`
+Rendered at the bottom of all the items. Can be a React Component Class, a render function, or a rendered element.
| Type | Required |
| - | - |
-| | No |
+| component, function, element | No |
+---
+
+
+### `ListHeaderComponent`
+
+Rendered at the top of all the items. Can be a React Component Class, a render function, or a rendered element.
+
+| Type | Required |
+| - | - |
+| component, function, element | No |
---
-### `maxToRenderPerBatch`
+### `onLayout`
+| Type | Required |
+| - | - |
+| function | No |
+
+
+---
+
+
+### `onRefresh`
+
+```javascript
+() => void
+```
+
+If provided, a standard `RefreshControl` will be added for "Pull to Refresh" functionality. Make sure to also set the `refreshing` prop correctly.
| Type | Required |
| - | - |
-| | No |
+| function | No |
+
+
+---
+
+### `onScrollToIndexFailed`
+```javascript
+(info: {
+ index: number,
+ highestMeasuredFrameIndex: number,
+ averageItemLength: number,
+ }) => void
+```
+
+Used to handle failures when scrolling to an index that has not been measured yet. Recommended action is to either compute your own offset and `scrollTo` it, or scroll as far as possible and then try again after more items have been rendered.
+
+| Type | Required |
+| - | - |
+| function | No |
---
-### `onEndReachedThreshold`
+### `onViewableItemsChanged`
+
+```javascript
+(info: {
+ viewableItems: array,
+ changed: array,
+ }) => void
+```
+Called when the viewability of rows changes, as defined by the `viewabilityConfig` prop.
| Type | Required |
| - | - |
-| | No |
+| function | No |
+
+
+
+---
+
+
+### `refreshing`
+
+Set this true while waiting for new data from a refresh.
+
+| Type | Required |
+| - | - |
+| boolean | No |
+
+
+---
+
+
+### `removeClippedSubviews`
+
+This may improve scroll performance for large lists.
+
+> Note:
+> May have bugs (missing content) in some circumstances - use at your own risk.
+
+| Type | Required |
+| - | - |
+| boolean | No |
+
+
+---
+
+
+### `renderScrollComponent`
+
+```javascript
+(props: object) => element
+```
+
+Render a custom scroll component, e.g. with a differently styled `RefreshControl`.
+
+| Type | Required |
+| - | - |
+| function | No |
+
+
+---
+
+
+### `viewabilityConfig`
+
+See `ViewabilityHelper.js` for flow type and further documentation.
+
+| Type | Required |
+| - | - |
+| ViewabilityConfig | No |
+
+
+
+---
+
+
+### `viewabilityConfigCallbackPairs`
+
+List of `ViewabilityConfig`/`onViewableItemsChanged` pairs. A specific `onViewableItemsChanged` will be called when its corresponding `ViewabilityConfig`'s conditions are met. See `ViewabilityHelper.js` for flow type and further documentation.
+
+| Type | Required |
+| - | - |
+| array of ViewabilityConfigCallbackPair | No |
+
+
+---
+
+
+
+### `horizontal`
+
+
+
+| Type | Required |
+| - | - |
+| boolean | No |
+
+
+
+
+---
+
+### `initialNumToRender`
+
+How many items to render in the initial batch. This should be enough to fill the screen but not much more. Note these items will never be unmounted as part of the windowed rendering in order to improve perceived performance of scroll-to-top actions.
+
+| Type | Required |
+| - | - |
+| number | No |
+
+
+
+
+---
+
+### `keyExtractor`
+
+```javascript
+(item: object, index: number) => string
+```
+
+Used to extract a unique key for a given item at the specified index. Key is used for caching and as the react key to track item re-ordering. The default extractor checks `item.key`, then falls back to using the index, like React does.
+
+| Type | Required |
+| - | - |
+| function | No |
+
+
+
+---
+
+### `maxToRenderPerBatch`
+
+The maximum number of items to render in each incremental render batch. The more rendered at once, the better the fill rate, but responsiveness my suffer because rendering content may interfere with responding to button taps or other interactions.
+
+| Type | Required |
+| - | - |
+| number | No |
+
+
+---
+
+### `onEndReached`
+
+```javascript
+(info: {distanceFromEnd: number}) => void
+```
+
+Called once when the scroll position gets within `onEndReachedThreshold` of the rendered content.
+
+| Type | Required |
+| - | - |
+| function | No |
+
+---
+
+### `onEndReachedThreshold`
+
+ How far from the end (in units of visible length of the list) the bottom edge of the list must be from the end of the content to trigger the `onEndReached` callback. Thus a value of 0.5 will trigger `onEndReached` when the end of the content is within half the visible length of the list.
+
+| Type | Required |
+| - | - |
+| number | No |
+
@@ -193,11 +484,11 @@ Some caveats:
### `updateCellsBatchingPeriod`
-
+Amount of time between low-pri item render batches, e.g. for rendering items quite a ways off screen. Similar fill rate/responsiveness tradeoff as `maxToRenderPerBatch`.
| Type | Required |
| - | - |
-| | No |
+| number | No |
@@ -206,15 +497,56 @@ Some caveats:
### `windowSize`
+Determines the maximum number of items rendered outside of the visible area, in units of visible lengths. So if your list fills the screen, then `windowSize={21}` (the default) will render the visible screen area plus up to 10 screens above and 10 below the viewport. Reducing this number will reduce memory consumption and may improve performance, but will increase the chance that fast scrolling may reveal momentary blank areas of unrendered content.
+
+
+| Type | Required |
+| - | - |
+| number | No |
+
+
+---
+
+### `disableVirtualization`
+
+**DEPRECATED.** Virtualization provides significant performance and memory optimizations, but fully unmounts react instances that are outside of the render window. You should only need to disable this for debugging purposes.
| Type | Required |
| - | - |
| | No |
+---
+
+
+### `progressViewOffset`
+
+Set this when offset is needed for the loading indicator to show correctly.
+| Type | Required | Platform |
+| - | - | - |
+| number | No | Android |
+## State
+
+### `first`
+
+
+
+| Type |
+| - |
+| number |
+
+---
+
+### `last`
+
+
+| Type |
+| - |
+| number |
+
## Methods
@@ -257,12 +589,11 @@ scrollToOffset(params: object)
Scroll to a specific content pixel offset in the list.
-Param `offset` expects the offset to scroll to.
-In case of `horizontal` is true, the offset is the x-value,
-in any other case the offset is the y-value.
+**Parameters:**
-Param `animated` (`true` by default) defines whether the list
-should do an animation while scrolling.
+- `offset` expects the offset to scroll to.
+ In case of `horizontal` is true, the offset is the x-value, in any other case the offset is the y-value.
+- `animated` (`true` by default) defines whether the list should do an animation while scrolling.
diff --git a/docs/webview.md b/docs/webview.md
index 60071707742ba1..bb2b5eea59160e 100644
--- a/docs/webview.md
+++ b/docs/webview.md
@@ -30,7 +30,7 @@ history and configure various properties for the web content.
### Props
-* [ViewPropTypes props...](docs/viewproptypes.html#props)
+- [View props...](docs/view-props.html)
- [`source`](docs/webview.html#source)
- [`automaticallyAdjustContentInsets`](docs/webview.html#automaticallyadjustcontentinsets)
- [`injectJavaScript`](docs/webview.html#injectjavascript)
@@ -85,8 +85,23 @@ Loads static html or a uri (with optional headers) in the WebView.
| Type | Required |
| - | - |
-| object: {uri: string,method: string,headers: object,body: string}, ,object: {html: string,baseUrl: string}, ,number | No |
+| object: {uri: string, method: string, headers: object, body: string},object: {html: string, baseUrl: string}, number | No |
+**Keys:**
+
+An object with either set of keys can be used. Shape:
+
+- `uri` - The URI to load in the `WebView`. Can be a local or remote file.
+- `method` - The HTTP Method to use. Defaults to GET if not specified. On Android, only GET and POST are supported.
+- `headers` - Additional HTTP headers to send with the request. On Android, this can only be used with GET requests.
+- `body` - The HTTP body to send with the request. This must be a valid UTF-8 string, and will be sent exactly as specified, with no additional encoding (e.g. URL-escaping or base64) applied. On Android, this can only be used with POST requests.
+
+Shape:
+
+- `html` - A static HTML page to display in the WebView.
+- `baseUrl` - The base URL to be used for any relative links in the HTML.
+
+The packager uses a third type, `number`, internally.
@@ -151,14 +166,17 @@ to tap them before they start playing. The default value is `true`.
### `nativeConfig`
-Override the native component used to render the WebView. Enables a custom native
-WebView which uses the same JavaScript as the original WebView.
+Override the native component used to render the WebView. Enables a custom native WebView which uses the same JavaScript as the original WebView.
| Type | Required |
| - | - |
| object: {component: any,props: object,viewManager: object} | No |
+**Keys:**
+- `component` - The native component used to render the WebView.
+- `props` - Set props directly on the native component WebView. Enables custom props which the original WebView doesn't pass through.
+- `viewManager` - Set the ViewManager to use for communication with the native side. iOS only.
---
@@ -324,7 +342,7 @@ The style to apply to the `WebView`.
| Type | Required |
| - | - |
-| ViewPropTypes.style | No |
+| [ViewPropTypes.style](docs/viewproptypes.html#style) | No |
@@ -501,7 +519,7 @@ Possible values for `dataDetectorTypes` are:
| Type | Required | Platform |
| - | - | - |
-| enum('phoneNumber', 'link', 'address', 'calendarEvent', 'none', 'all'), ,array of enum('phoneNumber', 'link', 'address', 'calendarEvent', 'none', 'all') | No | iOS |
+| enum('phoneNumber', 'link', 'address', 'calendarEvent', 'none', 'all'), array of enum('phoneNumber', 'link', 'address', 'calendarEvent', 'none', 'all') | No | iOS |
@@ -558,7 +576,7 @@ Boolean value that determines whether scrolling is enabled in the
### `extraNativeComponentConfig()`
```javascript
-static extraNativeComponentConfig()
+WebView.extraNativeComponentConfig()
```
From 260e6d23554a8e7f1743263894c9ca9a0cfbf01e Mon Sep 17 00:00:00 2001
From: Dmitry Zakharov
Date: Thu, 9 Nov 2017 09:49:34 -0800
Subject: [PATCH 07/50] Remove shared bridge experiment
Reviewed By: kathryngray
Differential Revision: D6284437
fbshipit-source-id: 14e0516f22dde04c0bbc4eb8fac603590d32d66a
---
.../facebook/react/ReactInstanceManager.java | 35 ++++++-------------
.../react/ReactInstanceManagerBuilder.java | 14 --------
2 files changed, 10 insertions(+), 39 deletions(-)
diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java
index ab850f9cf521fe..aa317e7503bb4a 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java
@@ -236,8 +236,6 @@ public static ReactInstanceManagerBuilder builder() {
@Nullable DevBundleDownloadListener devBundleDownloadListener,
boolean useSeparateUIBackgroundThread,
int minNumShakes,
- boolean splitPackagesEnabled,
- boolean useOnlyDefaultPackages,
int minTimeLeftInFrameForNonBatchedOperationMs) {
Log.d(ReactConstants.TAG, "ReactInstanceManager.ctor()");
initializeSoLoaderIfNecessary(applicationContext);
@@ -273,30 +271,17 @@ public static ReactInstanceManagerBuilder builder() {
mUseSeparateUIBackgroundThread = useSeparateUIBackgroundThread;
mMinNumShakes = minNumShakes;
synchronized (mPackages) {
- if (!splitPackagesEnabled) {
- CoreModulesPackage coreModulesPackage =
- new CoreModulesPackage(
- this,
- mBackBtnHandler,
- mUIImplementationProvider,
- mLazyViewManagersEnabled,
- mMinTimeLeftInFrameForNonBatchedOperationMs);
- mPackages.add(coreModulesPackage);
- } else {
- PrinterHolder.getPrinter().logMessage(ReactDebugOverlayTags.RN_CORE, "RNCore: Use Split Packages");
- mPackages.add(new BridgeCorePackage(this, mBackBtnHandler));
- if (mUseDeveloperSupport) {
- mPackages.add(new DebugCorePackage());
- }
- if (!useOnlyDefaultPackages) {
- mPackages.add(
- new ReactNativeCorePackage(
- this,
- mUIImplementationProvider,
- mLazyViewManagersEnabled,
- mMinTimeLeftInFrameForNonBatchedOperationMs));
- }
+ PrinterHolder.getPrinter().logMessage(ReactDebugOverlayTags.RN_CORE, "RNCore: Use Split Packages");
+ mPackages.add(new BridgeCorePackage(this, mBackBtnHandler));
+ if (mUseDeveloperSupport) {
+ mPackages.add(new DebugCorePackage());
}
+ mPackages.add(
+ new ReactNativeCorePackage(
+ this,
+ mUIImplementationProvider,
+ mLazyViewManagersEnabled,
+ mMinTimeLeftInFrameForNonBatchedOperationMs));
mPackages.addAll(packages);
}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java
index 59eaa71e724161..2fbaaa2b80c339 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java
@@ -48,8 +48,6 @@ public class ReactInstanceManagerBuilder {
private @Nullable JavaScriptExecutorFactory mJavaScriptExecutorFactory;
private boolean mUseSeparateUIBackgroundThread;
private int mMinNumShakes = 1;
- private boolean mEnableSplitPackage;
- private boolean mUseOnlyDefaultPackages;
private int mMinTimeLeftInFrameForNonBatchedOperationMs = -1;
/* package protected */ ReactInstanceManagerBuilder() {
@@ -227,16 +225,6 @@ public ReactInstanceManagerBuilder setMinNumShakes(int minNumShakes) {
return this;
}
- public ReactInstanceManagerBuilder setEnableSplitPackage(boolean enableSplitPackage) {
- mEnableSplitPackage = enableSplitPackage;
- return this;
- }
-
- public ReactInstanceManagerBuilder setUseOnlyDefaultPackages(boolean useOnlyDefaultPackages) {
- mUseOnlyDefaultPackages = useOnlyDefaultPackages;
- return this;
- }
-
public ReactInstanceManagerBuilder setMinTimeLeftInFrameForNonBatchedOperationMs(
int minTimeLeftInFrameForNonBatchedOperationMs) {
mMinTimeLeftInFrameForNonBatchedOperationMs = minTimeLeftInFrameForNonBatchedOperationMs;
@@ -300,8 +288,6 @@ public ReactInstanceManager build() {
mDevBundleDownloadListener,
mUseSeparateUIBackgroundThread,
mMinNumShakes,
- mEnableSplitPackage,
- mUseOnlyDefaultPackages,
mMinTimeLeftInFrameForNonBatchedOperationMs);
}
}
From e5a4ea97d9e1b13509a3f36d0b469a6a88a90dc4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?H=C3=A9ctor=20Ramos?=
<165856+hramos@users.noreply.github.com>
Date: Thu, 9 Nov 2017 10:56:52 -0800
Subject: [PATCH 08/50] Restore missing ejected banner
Summary:
A few more docs where the ejected metadata was lost in the autodocs flattening transition that happened in 9ec95673909beac7798f589e0e9821b4225f8fa9.
Closes https://github.com/facebook/react-native/pull/16773
Differential Revision: D6286368
Pulled By: hramos
fbshipit-source-id: bb7c032ca386e473c393821ce031714168d31719
---
docs/running-on-device.md | 1 +
docs/running-on-simulator-ios.md | 1 +
docs/signed-apk-android.md | 1 +
docs/understanding-cli.md | 1 +
4 files changed, 4 insertions(+)
diff --git a/docs/running-on-device.md b/docs/running-on-device.md
index 1ecaf330931985..e4ef2dff9ee258 100644
--- a/docs/running-on-device.md
+++ b/docs/running-on-device.md
@@ -4,6 +4,7 @@ title: Running On Device
layout: docs
category: Guides
permalink: docs/running-on-device.html
+banner: ejected
next: upgrading
previous: integration-with-existing-apps
---
diff --git a/docs/running-on-simulator-ios.md b/docs/running-on-simulator-ios.md
index 8005ea17283455..950412009f6032 100644
--- a/docs/running-on-simulator-ios.md
+++ b/docs/running-on-simulator-ios.md
@@ -4,6 +4,7 @@ title: Running On Simulator
layout: docs
category: Guides (iOS)
permalink: docs/running-on-simulator-ios.html
+banner: ejected
next: communication-ios
previous: linking-libraries-ios
---
diff --git a/docs/signed-apk-android.md b/docs/signed-apk-android.md
index 21ba2ec3e79087..b96bbbf68f6304 100644
--- a/docs/signed-apk-android.md
+++ b/docs/signed-apk-android.md
@@ -4,6 +4,7 @@ title: Generating Signed APK
layout: docs
category: Guides (Android)
permalink: docs/signed-apk-android.html
+banner: ejected
next: android-building-from-source
previous: headless-js-android
---
diff --git a/docs/understanding-cli.md b/docs/understanding-cli.md
index 6b728506a2008f..6831b545303262 100644
--- a/docs/understanding-cli.md
+++ b/docs/understanding-cli.md
@@ -4,6 +4,7 @@ title: Understanding the CLI
layout: docs
category: Contributing
permalink: docs/understanding-cli.html
+banner: ejected
next: activityindicator
previous: testing
---
From 820cfa1f3b79406e47cb873773cadafefe0effb1 Mon Sep 17 00:00:00 2001
From: James Isaac
Date: Thu, 9 Nov 2017 11:41:08 -0800
Subject: [PATCH 09/50] Refine StyleSheet Flow types
Summary:
Nice addition of the recent Flow types for style props in 9c29ee1504a66979d7e87f60e42d437e044a1ada, however I think there are some slight issues in the definition.
`type Styles = {[key: string]: Object}` makes sense, as it's referring to the set of named style groups a user creates a `StyleSheet` from, e.g.
```javascript
const styles: StyleSheet = StyleSheet.create({
container: {
height: 20
},
text: {
color: '#999',
fontSize: 12,
},
}: Styles)
```
However `type StyleValue = {[key: string]: Object}` doesn't make sense. You actually want only the `Object` portion of that definition, presuming it's meant to be used like below:
```javascript
type MyTextProps = {
style: StyleProp,
}
Hello
```
---
I've also added `void` to the `StyleValue`, as undefined seems to be handled fine, and can be a useful shorthand in JSX.
---
And finally, I've allowed nesting of style prop arrays, by making StyleProp self-referencing, as RN seems to flatten those without issue. This can be important if you're passing in a style prop quite high up the component tree, and sticking it in an array with other styles at several points while it's passed down.
N/A (These types aren't referenced anywhere else)
[INTERNAL] [MINOR] [StyleSheet] - Refine Flow types
Closes https://github.com/facebook/react-native/pull/16741
Reviewed By: frantic
Differential Revision: D6278010
Pulled By: TheSavior
fbshipit-source-id: 0170a233ab71d29f445786f5e695463f9730db3a
---
Libraries/StyleSheet/StyleSheet.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Libraries/StyleSheet/StyleSheet.js b/Libraries/StyleSheet/StyleSheet.js
index 8fd9b1f6cd5141..411cad91b7c44d 100644
--- a/Libraries/StyleSheet/StyleSheet.js
+++ b/Libraries/StyleSheet/StyleSheet.js
@@ -20,8 +20,8 @@ const flatten = require('flattenStyle');
export type Styles = {[key: string]: Object};
export type StyleSheet = {[key: $Keys]: number};
-export type StyleValue = {[key: string]: Object} | number | false | null;
-export type StyleProp = StyleValue | Array;
+export type StyleValue = Object | number | false | null | void | '';
+export type StyleProp = StyleValue | Array;
let hairlineWidth = PixelRatio.roundToNearestPixel(0.4);
if (hairlineWidth === 0) {
From cff0d8e0e599d1ab21b36779b41fbb26512874aa Mon Sep 17 00:00:00 2001
From: Alex Dvornikov
Date: Thu, 9 Nov 2017 11:55:37 -0800
Subject: [PATCH 10/50] Register split segment paths with RAMBundleRegistry
Differential Revision: D6284466
fbshipit-source-id: c80cf929af38f92f06cca5b366c58785ae992d83
---
React/CxxBridge/RCTCxxBridge.mm | 2 +-
React/CxxBridge/RCTObjcExecutor.mm | 4 ++++
.../main/jni/react/jni/CatalystInstanceImpl.cpp | 2 +-
.../src/main/jni/react/jni/ProxyExecutor.cpp | 6 ++++++
.../src/main/jni/react/jni/ProxyExecutor.h | 2 ++
ReactCommon/cxxreact/Instance.cpp | 4 ++++
ReactCommon/cxxreact/Instance.h | 3 +++
ReactCommon/cxxreact/JSCExecutor.cpp | 6 ++++++
ReactCommon/cxxreact/JSCExecutor.h | 1 +
ReactCommon/cxxreact/JSExecutor.h | 5 +++++
ReactCommon/cxxreact/JSIndexedRAMBundle.cpp | 7 +++----
ReactCommon/cxxreact/JSIndexedRAMBundle.h | 2 +-
ReactCommon/cxxreact/NativeToJsBridge.cpp | 6 ++++++
ReactCommon/cxxreact/NativeToJsBridge.h | 1 +
ReactCommon/cxxreact/RAMBundleRegistry.cpp | 15 ++++++++++++---
ReactCommon/cxxreact/RAMBundleRegistry.h | 9 ++++++---
16 files changed, 62 insertions(+), 13 deletions(-)
diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm
index 871bc46071c255..b5ce3026b2553a 100644
--- a/React/CxxBridge/RCTCxxBridge.mm
+++ b/React/CxxBridge/RCTCxxBridge.mm
@@ -1152,7 +1152,7 @@ - (void)executeApplicationScript:(NSData *)script
? [[self.delegate jsSegmentsDirectory].path stringByAppendingString:@"/"]
: nil;
auto registry = jsSegmentsDirectory != nil
- ? RAMBundleRegistry::multipleBundlesRegistry(std::move(ramBundle), JSIndexedRAMBundle::buildFactory(jsSegmentsDirectory.UTF8String))
+ ? RAMBundleRegistry::multipleBundlesRegistry(std::move(ramBundle), JSIndexedRAMBundle::buildFactory())
: RAMBundleRegistry::singleBundleRegistry(std::move(ramBundle));
self->_reactInstance->loadRAMBundle(std::move(registry), std::move(scriptStr),
sourceUrlStr.UTF8String, !async);
diff --git a/React/CxxBridge/RCTObjcExecutor.mm b/React/CxxBridge/RCTObjcExecutor.mm
index 53c32368d5b15e..476bcff9b40709 100644
--- a/React/CxxBridge/RCTObjcExecutor.mm
+++ b/React/CxxBridge/RCTObjcExecutor.mm
@@ -95,6 +95,10 @@ void setBundleRegistry(std::unique_ptr) override {
RCTAssert(NO, @"RAM bundles are not supported in RCTObjcExecutor");
}
+ void registerBundle(uint32_t bundleId, const std::string &bundlePath) override {
+ RCTAssert(NO, @"RAM bundles are not supported in RCTObjcExecutor");
+ }
+
void callFunction(const std::string &module, const std::string &method,
const folly::dynamic &arguments) override {
[m_jse callFunctionOnModule:@(module.c_str())
diff --git a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp
index 3bcc53aa8318e9..4ca32b7b9c44b5 100644
--- a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp
+++ b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp
@@ -212,7 +212,7 @@ void CatalystInstanceImpl::jniLoadScriptFromFile(const std::string& fileName,
auto script = bundle->getStartupCode();
auto registry = jsSegmentsDirectory_.empty()
? RAMBundleRegistry::singleBundleRegistry(std::move(bundle))
- : RAMBundleRegistry::multipleBundlesRegistry(std::move(bundle), JSIndexedRAMBundle::buildFactory(jsSegmentsDirectory_));
+ : RAMBundleRegistry::multipleBundlesRegistry(std::move(bundle), JSIndexedRAMBundle::buildFactory());
instance_->loadRAMBundle(
std::move(registry),
std::move(script),
diff --git a/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.cpp b/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.cpp
index d79f4f96d6e30c..1b9395ceae4c9f 100644
--- a/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.cpp
+++ b/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.cpp
@@ -90,6 +90,12 @@ void ProxyExecutor::setBundleRegistry(std::unique_ptr) {
"Loading application RAM bundles is not supported for proxy executors");
}
+void ProxyExecutor::registerBundle(uint32_t bundleId, const std::string& bundlePath) {
+ jni::throwNewJavaException(
+ "java/lang/UnsupportedOperationException",
+ "Loading application RAM bundles is not supported for proxy executors");
+}
+
void ProxyExecutor::callFunction(const std::string& moduleId, const std::string& methodId, const folly::dynamic& arguments) {
auto call = folly::dynamic::array(moduleId, methodId, std::move(arguments));
diff --git a/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.h b/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.h
index 30758073a79eef..b77d35f63745cd 100644
--- a/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.h
+++ b/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.h
@@ -37,6 +37,8 @@ class ProxyExecutor : public JSExecutor {
std::string sourceURL) override;
virtual void setBundleRegistry(
std::unique_ptr bundle) override;
+ virtual void registerBundle(
+ uint32_t bundleId, const std::string& bundlePath) override;
virtual void callFunction(
const std::string& moduleId,
const std::string& methodId,
diff --git a/ReactCommon/cxxreact/Instance.cpp b/ReactCommon/cxxreact/Instance.cpp
index 271dc85815d291..bdf1fce1eee280 100644
--- a/ReactCommon/cxxreact/Instance.cpp
+++ b/ReactCommon/cxxreact/Instance.cpp
@@ -156,6 +156,10 @@ void Instance::callJSCallback(uint64_t callbackId, folly::dynamic &¶ms) {
nativeToJsBridge_->invokeCallback((double)callbackId, std::move(params));
}
+void Instance::registerBundle(uint32_t bundleId, const std::string& bundlePath) {
+ nativeToJsBridge_->registerBundle(bundleId, bundlePath);
+}
+
const ModuleRegistry &Instance::getModuleRegistry() const {
return *moduleRegistry_;
}
diff --git a/ReactCommon/cxxreact/Instance.h b/ReactCommon/cxxreact/Instance.h
index 6999fb60de1edc..d04bcb3563721c 100644
--- a/ReactCommon/cxxreact/Instance.h
+++ b/ReactCommon/cxxreact/Instance.h
@@ -59,6 +59,9 @@ class RN_EXPORT Instance {
folly::dynamic &¶ms);
void callJSCallback(uint64_t callbackId, folly::dynamic &¶ms);
+ // This method is experimental, and may be modified or removed.
+ void registerBundle(uint32_t bundleId, const std::string& bundlePath);
+
// This method is experimental, and may be modified or removed.
template
Value callFunctionSync(const std::string &module, const std::string &method,
diff --git a/ReactCommon/cxxreact/JSCExecutor.cpp b/ReactCommon/cxxreact/JSCExecutor.cpp
index 3dfe2db47257d4..0b66c8c3c6da8f 100644
--- a/ReactCommon/cxxreact/JSCExecutor.cpp
+++ b/ReactCommon/cxxreact/JSCExecutor.cpp
@@ -458,6 +458,12 @@ namespace facebook {
m_bundleRegistry = std::move(bundleRegistry);
}
+ void JSCExecutor::registerBundle(uint32_t bundleId, const std::string& bundlePath) {
+ if (m_bundleRegistry) {
+ m_bundleRegistry->registerBundle(bundleId, bundlePath);
+ }
+ }
+
void JSCExecutor::bindBridge() throw(JSException) {
SystraceSection s("JSCExecutor::bindBridge");
std::call_once(m_bindFlag, [this] {
diff --git a/ReactCommon/cxxreact/JSCExecutor.h b/ReactCommon/cxxreact/JSCExecutor.h
index f2dc8c61ed571d..c646677d6022c4 100644
--- a/ReactCommon/cxxreact/JSCExecutor.h
+++ b/ReactCommon/cxxreact/JSCExecutor.h
@@ -66,6 +66,7 @@ class RN_EXPORT JSCExecutor : public JSExecutor, public PrivateDataBase {
std::string sourceURL) override;
virtual void setBundleRegistry(std::unique_ptr bundleRegistry) override;
+ virtual void registerBundle(uint32_t bundleId, const std::string& bundlePath) override;
virtual void callFunction(
const std::string& moduleId,
diff --git a/ReactCommon/cxxreact/JSExecutor.h b/ReactCommon/cxxreact/JSExecutor.h
index b8cc3d3f13709d..83f9e15344fbd7 100644
--- a/ReactCommon/cxxreact/JSExecutor.h
+++ b/ReactCommon/cxxreact/JSExecutor.h
@@ -53,6 +53,11 @@ class JSExecutor {
*/
virtual void setBundleRegistry(std::unique_ptr bundleRegistry) = 0;
+ /**
+ * Register a file path for an additional "RAM" bundle
+ */
+ virtual void registerBundle(uint32_t bundleId, const std::string& bundlePath) = 0;
+
/**
* Executes BatchedBridge.callFunctionReturnFlushedQueue with the module ID,
* method ID and optional additional arguments in JS. The executor is responsible
diff --git a/ReactCommon/cxxreact/JSIndexedRAMBundle.cpp b/ReactCommon/cxxreact/JSIndexedRAMBundle.cpp
index 51672048570e99..b5db5203fa74ad 100644
--- a/ReactCommon/cxxreact/JSIndexedRAMBundle.cpp
+++ b/ReactCommon/cxxreact/JSIndexedRAMBundle.cpp
@@ -9,10 +9,9 @@
namespace facebook {
namespace react {
-std::function(uint32_t)> JSIndexedRAMBundle::buildFactory(const std::string& baseDirectoryPath) {
- return [baseDirectoryPath](uint32_t index){
- std::string bundlePathById = baseDirectoryPath + toString(index) + ".jsbundle";
- return folly::make_unique(bundlePathById.c_str());
+std::function(std::string)> JSIndexedRAMBundle::buildFactory() {
+ return [](const std::string& bundlePath){
+ return folly::make_unique(bundlePath.c_str());
};
}
diff --git a/ReactCommon/cxxreact/JSIndexedRAMBundle.h b/ReactCommon/cxxreact/JSIndexedRAMBundle.h
index 3d4341b4a40a1b..6467977279fa53 100644
--- a/ReactCommon/cxxreact/JSIndexedRAMBundle.h
+++ b/ReactCommon/cxxreact/JSIndexedRAMBundle.h
@@ -17,7 +17,7 @@ namespace react {
class RN_EXPORT JSIndexedRAMBundle : public JSModulesUnbundle {
public:
- static std::function(uint32_t)> buildFactory(const std::string& baseDirectoryPath);
+ static std::function(std::string)> buildFactory();
// Throws std::runtime_error on failure.
JSIndexedRAMBundle(const char *sourceURL);
diff --git a/ReactCommon/cxxreact/NativeToJsBridge.cpp b/ReactCommon/cxxreact/NativeToJsBridge.cpp
index 3f1f78c8336637..51bad86f746f92 100644
--- a/ReactCommon/cxxreact/NativeToJsBridge.cpp
+++ b/ReactCommon/cxxreact/NativeToJsBridge.cpp
@@ -171,6 +171,12 @@ void NativeToJsBridge::invokeCallback(double callbackId, folly::dynamic&& argume
});
}
+void NativeToJsBridge::registerBundle(uint32_t bundleId, const std::string& bundlePath) {
+ runOnExecutorQueue([bundleId, bundlePath] (JSExecutor* executor) {
+ executor->registerBundle(bundleId, bundlePath);
+ });
+}
+
void NativeToJsBridge::setGlobalVariable(std::string propName,
std::unique_ptr jsonValue) {
runOnExecutorQueue([propName=std::move(propName), jsonValue=folly::makeMoveWrapper(std::move(jsonValue))]
diff --git a/ReactCommon/cxxreact/NativeToJsBridge.h b/ReactCommon/cxxreact/NativeToJsBridge.h
index dee12b6e3273b3..093707f2e8215a 100644
--- a/ReactCommon/cxxreact/NativeToJsBridge.h
+++ b/ReactCommon/cxxreact/NativeToJsBridge.h
@@ -98,6 +98,7 @@ class NativeToJsBridge {
std::unique_ptr startupCode,
std::string sourceURL);
+ void registerBundle(uint32_t bundleId, const std::string& bundlePath);
void setGlobalVariable(std::string propName, std::unique_ptr jsonValue);
void* getJavaScriptContext();
diff --git a/ReactCommon/cxxreact/RAMBundleRegistry.cpp b/ReactCommon/cxxreact/RAMBundleRegistry.cpp
index 896eeb5f649c15..635875b3b79cbe 100644
--- a/ReactCommon/cxxreact/RAMBundleRegistry.cpp
+++ b/ReactCommon/cxxreact/RAMBundleRegistry.cpp
@@ -16,21 +16,30 @@ std::unique_ptr RAMBundleRegistry::singleBundleRegistry(std::
return std::unique_ptr(registry);
}
-std::unique_ptr RAMBundleRegistry::multipleBundlesRegistry(std::unique_ptr mainBundle, std::function(uint32_t)> factory) {
+std::unique_ptr RAMBundleRegistry::multipleBundlesRegistry(std::unique_ptr mainBundle, std::function(std::string)> factory) {
RAMBundleRegistry *registry = new RAMBundleRegistry(std::move(mainBundle), std::move(factory));
return std::unique_ptr(registry);
}
-RAMBundleRegistry::RAMBundleRegistry(std::unique_ptr mainBundle, std::function(uint32_t)> factory): m_factory(factory) {
+RAMBundleRegistry::RAMBundleRegistry(std::unique_ptr mainBundle, std::function(std::string)> factory): m_factory(factory) {
m_bundles.emplace(MAIN_BUNDLE_ID, std::move(mainBundle));
}
+void RAMBundleRegistry::registerBundle(uint32_t bundleId, std::string bundlePath) {
+ m_bundlePaths.emplace(bundleId, bundlePath);
+}
+
JSModulesUnbundle::Module RAMBundleRegistry::getModule(uint32_t bundleId, uint32_t moduleId) {
if (m_bundles.find(bundleId) == m_bundles.end()) {
if (!m_factory) {
throw std::runtime_error("You need to register factory function in order to support multiple RAM bundles.");
}
- m_bundles.emplace(bundleId, m_factory(bundleId));
+
+ auto bundlePath = m_bundlePaths.find(bundleId);
+ if (bundlePath == m_bundlePaths.end()) {
+ throw std::runtime_error("In order to fetch RAM bundle from the registry, its file path needs to be registered first.");
+ }
+ m_bundles.emplace(bundleId, m_factory(bundlePath->second));
}
return getBundle(bundleId)->getModule(moduleId);
diff --git a/ReactCommon/cxxreact/RAMBundleRegistry.h b/ReactCommon/cxxreact/RAMBundleRegistry.h
index cb845a4751e29f..2d628f22c35d7c 100644
--- a/ReactCommon/cxxreact/RAMBundleRegistry.h
+++ b/ReactCommon/cxxreact/RAMBundleRegistry.h
@@ -21,21 +21,24 @@ namespace react {
class RN_EXPORT RAMBundleRegistry : noncopyable {
public:
using unique_ram_bundle = std::unique_ptr;
+ using bundle_path = std::string;
constexpr static uint32_t MAIN_BUNDLE_ID = 0;
static std::unique_ptr singleBundleRegistry(unique_ram_bundle mainBundle);
- static std::unique_ptr multipleBundlesRegistry(unique_ram_bundle mainBundle, std::function factory);
+ static std::unique_ptr multipleBundlesRegistry(unique_ram_bundle mainBundle, std::function factory);
RAMBundleRegistry(RAMBundleRegistry&&) = default;
RAMBundleRegistry& operator=(RAMBundleRegistry&&) = default;
+ void registerBundle(uint32_t bundleId, bundle_path bundlePath);
JSModulesUnbundle::Module getModule(uint32_t bundleId, uint32_t moduleId);
virtual ~RAMBundleRegistry() {};
private:
- explicit RAMBundleRegistry(unique_ram_bundle mainBundle, std::function factory = {});
+ explicit RAMBundleRegistry(unique_ram_bundle mainBundle, std::function factory = {});
JSModulesUnbundle *getBundle(uint32_t bundleId) const;
- std::function m_factory;
+ std::function m_factory;
+ std::unordered_map m_bundlePaths;
std::unordered_map m_bundles;
};
From 681278947eb4039a1d7a65f1edfeef25ae055a4f Mon Sep 17 00:00:00 2001
From: Alex Dvornikov
Date: Thu, 9 Nov 2017 11:55:39 -0800
Subject: [PATCH 11/50] Adopt new split segments registration approach on iOS
Differential Revision: D6284479
fbshipit-source-id: d0d7e8c6a6ce4ecab63739149be69f25df7fbe6f
---
React/Base/RCTBridge.h | 7 +++++++
React/Base/RCTBridge.m | 5 +++++
React/Base/RCTBridgeDelegate.h | 7 -------
React/CxxBridge/RCTCxxBridge.mm | 14 ++++++++------
4 files changed, 20 insertions(+), 13 deletions(-)
diff --git a/React/Base/RCTBridge.h b/React/Base/RCTBridge.h
index 450a0d0e38a104..99ad085225f25a 100644
--- a/React/Base/RCTBridge.h
+++ b/React/Base/RCTBridge.h
@@ -138,6 +138,13 @@ RCT_EXTERN NSString *RCTBridgeModuleNameForClass(Class bridgeModuleClass);
arguments:(NSArray *)arguments
error:(NSError **)error;
+/**
+ * This method registers the file path of an additional JS segment by its ID.
+ *
+ * @experimental
+ */
+- (void)registerSegmentWithId:(NSUInteger)segmentId path:(NSString *)path;
+
/**
* Retrieve a bridge module instance by name or class. Note that modules are
* lazily instantiated, so calling these methods for the first time with a given
diff --git a/React/Base/RCTBridge.m b/React/Base/RCTBridge.m
index a8cef88c7bf4d9..33d8c977a9ea33 100644
--- a/React/Base/RCTBridge.m
+++ b/React/Base/RCTBridge.m
@@ -398,6 +398,11 @@ - (JSValue *)callFunctionOnModule:(NSString *)module
return [self.batchedBridge callFunctionOnModule:module method:method arguments:arguments error:error];
}
+- (void)registerSegmentWithId:(NSUInteger)segmentId path:(NSString *)path
+{
+ [self.batchedBridge registerSegmentWithId:segmentId path:path];
+}
+
@end
@implementation RCTBridge (JavaScriptCore)
diff --git a/React/Base/RCTBridgeDelegate.h b/React/Base/RCTBridgeDelegate.h
index f70a024188bad1..1609544a94ff3c 100644
--- a/React/Base/RCTBridgeDelegate.h
+++ b/React/Base/RCTBridgeDelegate.h
@@ -94,11 +94,4 @@
- (void)loadSourceForBridge:(RCTBridge *)bridge
withBlock:(RCTSourceLoadBlock)loadCallback;
-/**
- * Specifies the path to folder where additional bundles are located
- *
- * @experimental
- */
-- (NSURL *)jsSegmentsDirectory;
-
@end
diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm
index b5ce3026b2553a..e87196886cf1d8 100644
--- a/React/CxxBridge/RCTCxxBridge.mm
+++ b/React/CxxBridge/RCTCxxBridge.mm
@@ -1148,12 +1148,7 @@ - (void)executeApplicationScript:(NSData *)script
[self->_performanceLogger markStopForTag:RCTPLRAMBundleLoad];
[self->_performanceLogger setValue:scriptStr->size() forTag:RCTPLRAMStartupCodeSize];
if (self->_reactInstance) {
- NSString *jsSegmentsDirectory = [self.delegate respondsToSelector:@selector(jsSegmentsDirectory)]
- ? [[self.delegate jsSegmentsDirectory].path stringByAppendingString:@"/"]
- : nil;
- auto registry = jsSegmentsDirectory != nil
- ? RAMBundleRegistry::multipleBundlesRegistry(std::move(ramBundle), JSIndexedRAMBundle::buildFactory())
- : RAMBundleRegistry::singleBundleRegistry(std::move(ramBundle));
+ auto registry = RAMBundleRegistry::multipleBundlesRegistry(std::move(ramBundle), JSIndexedRAMBundle::buildFactory());
self->_reactInstance->loadRAMBundle(std::move(registry), std::move(scriptStr),
sourceUrlStr.UTF8String, !async);
}
@@ -1214,6 +1209,13 @@ - (JSValue *)callFunctionOnModule:(NSString *)module
return ret;
}
+- (void)registerSegmentWithId:(NSUInteger)segmentId path:(NSString *)path
+{
+ if (_reactInstance) {
+ _reactInstance->registerBundle(static_cast(segmentId), path.UTF8String);
+ }
+}
+
#pragma mark - Payload Processing
- (void)partialBatchDidFlush
From a47431ed74f0b7b2a03ca48e84f2243d08ef3bdd Mon Sep 17 00:00:00 2001
From: Alex Dvornikov
Date: Thu, 9 Nov 2017 11:55:41 -0800
Subject: [PATCH 12/50] Adopt split segments registration approach on Android
Differential Revision: D6284863
fbshipit-source-id: 0df6b90eb0cbeab4c8a2b11f1e4dcbd5d5dfab72
---
.../facebook/react/bridge/CatalystInstance.java | 3 +++
.../react/bridge/CatalystInstanceImpl.java | 7 ++++---
.../facebook/react/bridge/JSBundleLoader.java | 15 ---------------
.../main/jni/react/jni/CatalystInstanceImpl.cpp | 17 ++++-------------
.../main/jni/react/jni/CatalystInstanceImpl.h | 8 +++-----
ReactCommon/cxxreact/Instance.cpp | 2 +-
6 files changed, 15 insertions(+), 37 deletions(-)
diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java
index 518b9d32be3c8d..29f03a1a17c1e0 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java
@@ -86,6 +86,9 @@ void callFunction(
*/
void removeBridgeIdleDebugListener(NotThreadSafeBridgeIdleDebugListener listener);
+ /** This method registers the file path of an additional JS segment by its ID. */
+ void registerSegment(int segmentId, String path);
+
@VisibleForTesting
void setGlobalVariable(String propName, String jsonValue);
diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java
index 960f252917cc76..f9b883c3532a2f 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java
@@ -210,8 +210,9 @@ private native void initializeBridge(
jniSetSourceURL(remoteURL);
}
- /* package */ void setJsSegmentsDirectory(String directoryPath) {
- jniSetJsSegmentsDirectory(directoryPath);
+ @Override
+ public void registerSegment(int segmentId, String path) {
+ jniRegisterSegment(segmentId, path);
}
/* package */ void loadScriptFromAssets(AssetManager assetManager, String assetURL, boolean loadSynchronously) {
@@ -225,7 +226,7 @@ private native void initializeBridge(
}
private native void jniSetSourceURL(String sourceURL);
- private native void jniSetJsSegmentsDirectory(String directoryPath);
+ private native void jniRegisterSegment(int segmentId, String path);
private native void jniLoadScriptFromAssets(AssetManager assetManager, String assetURL, boolean loadSynchronously);
private native void jniLoadScriptFromFile(String fileName, String sourceURL, boolean loadSynchronously);
diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/JSBundleLoader.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/JSBundleLoader.java
index d2f3aa566d7367..7700071c55c02a 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/bridge/JSBundleLoader.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/JSBundleLoader.java
@@ -96,21 +96,6 @@ public String loadScript(CatalystInstanceImpl instance) {
};
}
- /**
- * This loader is used to wrap other loaders and set js segments directory before executing
- * application script.
- */
- public static JSBundleLoader createSplitBundlesLoader(
- final String jsSegmentsDirectory, final JSBundleLoader delegate) {
- return new JSBundleLoader() {
- @Override
- public String loadScript(CatalystInstanceImpl instance) {
- instance.setJsSegmentsDirectory(jsSegmentsDirectory);
- return delegate.loadScript(instance);
- }
- };
- }
-
/** Loads the script, returning the URL of the source it loaded. */
public abstract String loadScript(CatalystInstanceImpl instance);
}
diff --git a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp
index 4ca32b7b9c44b5..abac4d1b19e081 100644
--- a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp
+++ b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp
@@ -100,7 +100,7 @@ void CatalystInstanceImpl::registerNatives() {
makeNativeMethod("initializeBridge", CatalystInstanceImpl::initializeBridge),
makeNativeMethod("jniExtendNativeModules", CatalystInstanceImpl::extendNativeModules),
makeNativeMethod("jniSetSourceURL", CatalystInstanceImpl::jniSetSourceURL),
- makeNativeMethod("jniSetJsSegmentsDirectory", CatalystInstanceImpl::jniSetJsSegmentsDirectory),
+ makeNativeMethod("jniRegisterSegment", CatalystInstanceImpl::jniRegisterSegment),
makeNativeMethod("jniLoadScriptFromAssets", CatalystInstanceImpl::jniLoadScriptFromAssets),
makeNativeMethod("jniLoadScriptFromFile", CatalystInstanceImpl::jniLoadScriptFromFile),
makeNativeMethod("jniCallJSFunction", CatalystInstanceImpl::jniCallJSFunction),
@@ -177,8 +177,8 @@ void CatalystInstanceImpl::jniSetSourceURL(const std::string& sourceURL) {
instance_->setSourceURL(sourceURL);
}
-void CatalystInstanceImpl::jniSetJsSegmentsDirectory(const std::string& directoryPath) {
- jsSegmentsDirectory_ = directoryPath;
+void CatalystInstanceImpl::jniRegisterSegment(int segmentId, const std::string& path) {
+ instance_->registerBundle((uint32_t)segmentId, path);
}
void CatalystInstanceImpl::jniLoadScriptFromAssets(
@@ -208,16 +208,7 @@ void CatalystInstanceImpl::jniLoadScriptFromFile(const std::string& fileName,
const std::string& sourceURL,
bool loadSynchronously) {
if (Instance::isIndexedRAMBundle(fileName.c_str())) {
- auto bundle = folly::make_unique(fileName.c_str());
- auto script = bundle->getStartupCode();
- auto registry = jsSegmentsDirectory_.empty()
- ? RAMBundleRegistry::singleBundleRegistry(std::move(bundle))
- : RAMBundleRegistry::multipleBundlesRegistry(std::move(bundle), JSIndexedRAMBundle::buildFactory());
- instance_->loadRAMBundle(
- std::move(registry),
- std::move(script),
- sourceURL,
- loadSynchronously);
+ instance_->loadRAMBundleFromFile(fileName, sourceURL, loadSynchronously);
} else {
std::unique_ptr script;
RecoverableError::runRethrowingAsRecoverable(
diff --git a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h
index 01abcd87136ec7..8a94c8cc9f3807 100644
--- a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h
+++ b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h
@@ -60,10 +60,10 @@ class CatalystInstanceImpl : public jni::HybridClass {
void jniSetSourceURL(const std::string& sourceURL);
/**
- * Sets the path to folder where additional bundles are located.
- * Needs to be invoked before "loadScript" methods are called.
+ * Registers the file path of an additional JS segment by its ID.
+ *
*/
- void jniSetJsSegmentsDirectory(const std::string& directoryPath);
+ void jniRegisterSegment(int segmentId, const std::string& path);
void jniLoadScriptFromAssets(jni::alias_ref assetManager, const std::string& assetURL, bool loadSynchronously);
void jniLoadScriptFromFile(const std::string& fileName, const std::string& sourceURL, bool loadSynchronously);
@@ -74,8 +74,6 @@ class CatalystInstanceImpl : public jni::HybridClass {
jlong getJavaScriptContext();
void handleMemoryPressure(int pressureLevel);
- std::string jsSegmentsDirectory_;
-
// This should be the only long-lived strong reference, but every C++ class
// will have a weak reference.
std::shared_ptr instance_;
diff --git a/ReactCommon/cxxreact/Instance.cpp b/ReactCommon/cxxreact/Instance.cpp
index bdf1fce1eee280..01ead37316cba6 100644
--- a/ReactCommon/cxxreact/Instance.cpp
+++ b/ReactCommon/cxxreact/Instance.cpp
@@ -111,7 +111,7 @@ void Instance::loadRAMBundleFromFile(const std::string& sourcePath,
bool loadSynchronously) {
auto bundle = folly::make_unique(sourcePath.c_str());
auto startupScript = bundle->getStartupCode();
- auto registry = RAMBundleRegistry::singleBundleRegistry(std::move(bundle));
+ auto registry = RAMBundleRegistry::multipleBundlesRegistry(std::move(bundle), JSIndexedRAMBundle::buildFactory());
loadRAMBundle(
std::move(registry),
std::move(startupScript),
From 780938170b0add35e6a4151892154fa0aa5f6b57 Mon Sep 17 00:00:00 2001
From: Jessica Cao
Date: Thu, 9 Nov 2017 12:45:12 -0800
Subject: [PATCH 13/50] Backed out changeset eadb184eacdf
Reviewed By: fkgozali, hramos
Differential Revision: D6287083
fbshipit-source-id: 43c6e43a9d5411e71f51824f9443559b4e0a47e2
---
Libraries/Alert/Alert.js | 9 ++++-----
Libraries/Alert/AlertIOS.js | 12 +++++-------
2 files changed, 9 insertions(+), 12 deletions(-)
diff --git a/Libraries/Alert/Alert.js b/Libraries/Alert/Alert.js
index 6598175c0825d3..40666f70e35076 100644
--- a/Libraries/Alert/Alert.js
+++ b/Libraries/Alert/Alert.js
@@ -16,7 +16,6 @@ const NativeModules = require('NativeModules');
const Platform = require('Platform');
import type { AlertType, AlertButtonStyle } from 'AlertIOS';
-import type { Fbt } from 'fbt';
export type Buttons = Array<{
text?: string,
@@ -80,8 +79,8 @@ type Options = {
class Alert {
static alert(
- title: ?string | ?Fbt,
- message?: ?string | ?Fbt,
+ title: ?string,
+ message?: ?string,
buttons?: Buttons,
options?: Options,
type?: AlertType,
@@ -105,8 +104,8 @@ class Alert {
class AlertAndroid {
static alert(
- title: ?string | ?Fbt,
- message?: ?string | ?Fbt,
+ title: ?string,
+ message?: ?string,
buttons?: Buttons,
options?: Options,
): void {
diff --git a/Libraries/Alert/AlertIOS.js b/Libraries/Alert/AlertIOS.js
index 933df8512a3b95..375a4db56c96a2 100644
--- a/Libraries/Alert/AlertIOS.js
+++ b/Libraries/Alert/AlertIOS.js
@@ -12,9 +12,7 @@
*/
'use strict';
-const RCTAlertManager = require('NativeModules').AlertManager;
-
-import type { Fbt } from 'fbt';
+var RCTAlertManager = require('NativeModules').AlertManager;
/**
* An Alert button type
@@ -135,8 +133,8 @@ class AlertIOS {
* );
*/
static alert(
- title: ?string | ?Fbt,
- message?: ?string | ?Fbt,
+ title: ?string,
+ message?: ?string,
callbackOrButtons?: ?(() => void) | ButtonsArray,
type?: AlertType,
): void {
@@ -194,8 +192,8 @@ class AlertIOS {
* );
*/
static prompt(
- title: ?string | ?Fbt,
- message?: ?string | ?Fbt,
+ title: ?string,
+ message?: ?string,
callbackOrButtons?: ?((text: string) => void) | ButtonsArray,
type?: ?AlertType = 'plain-text',
defaultValue?: string,
From 1f40c95076297258a4194fd9c1b5af7002187c99 Mon Sep 17 00:00:00 2001
From: Alexey Lang
Date: Thu, 9 Nov 2017 12:58:05 -0800
Subject: [PATCH 14/50] Fix sections that come from React Fiber
Reviewed By: fkgozali
Differential Revision: D6235187
fbshipit-source-id: 55a49da9d81204f7a6199420beca1b096f7ea212
---
Libraries/Core/InitializeCore.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/Libraries/Core/InitializeCore.js b/Libraries/Core/InitializeCore.js
index 8a4e2218767836..2e3821410e3af1 100644
--- a/Libraries/Core/InitializeCore.js
+++ b/Libraries/Core/InitializeCore.js
@@ -101,6 +101,7 @@ if (!global.process.env.NODE_ENV) {
// Setup the Systrace profiling hooks if necessary
if (global.__RCTProfileIsProfiling) {
const Systrace = require('Systrace');
+ Systrace.installReactHook(true);
Systrace.setEnabled(true);
}
From e04f82ce2b482124121d8845fcdd8f94b8850d64 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?H=C3=A9ctor=20Ramos?=
Date: Thu, 9 Nov 2017 13:18:53 -0800
Subject: [PATCH 15/50] Fix website deploys on master
Summary:
Use newer CircleCI 2.0 environment variable names, being consistent with CircleCI config.
Closes https://github.com/facebook/react-native/pull/16778
Differential Revision: D6288751
Pulled By: hramos
fbshipit-source-id: 079ffaaea1ed3b715a12b07ed7738750672eee4e
---
website/publish-gh-pages.js | 177 +++++++++++++++++++-----------------
1 file changed, 94 insertions(+), 83 deletions(-)
diff --git a/website/publish-gh-pages.js b/website/publish-gh-pages.js
index d31c683c17a171..7ceea38ebb3d7a 100644
--- a/website/publish-gh-pages.js
+++ b/website/publish-gh-pages.js
@@ -25,6 +25,7 @@ const {
const CIRCLE_BRANCH = process.env.CIRCLE_BRANCH;
const CIRCLE_PROJECT_USERNAME = process.env.CIRCLE_PROJECT_USERNAME;
const CI_PULL_REQUEST = process.env.CI_PULL_REQUEST;
+const CIRCLE_PR_USERNAME = process.env.CIRCLE_PR_USERNAME;
const GIT_USER = process.env.GIT_USER;
const remoteBranch = `https://${GIT_USER}@github.com/facebook/react-native.git`;
@@ -33,6 +34,16 @@ if (!which('git')) {
exit(1);
}
+if (CIRCLE_PR_USERNAME) {
+ echo('Skipping website deployment, this build was triggered from a commit in a pull request.');
+ exit(0);
+}
+
+if (CIRCLE_PROJECT_USERNAME !== 'facebook') {
+ echo('Skipping website deployment, this build was not triggered by a commit on the Facebook org.');
+ exit(0);
+}
+
let version;
let areVersionlessSectionsToBeDeployed = false;
if (CIRCLE_BRANCH.indexOf('-stable') !== -1) {
@@ -45,107 +56,107 @@ if (CIRCLE_BRANCH.indexOf('-stable') !== -1) {
rm('-rf', 'build');
mkdir('-p', 'build');
// if current commit is tagged "latest" we do a release to gh-pages root
+echo('Current commit:');
const currentCommit = exec('git rev-parse HEAD').stdout.trim();
+echo('Searching for commit tagged "latest"...');
const latestTagCommit = exec('git ls-remote origin latest').stdout.split(/\s/)[0];
// pass along which branch contains latest version so that gh-pages root could mark it as latest
+echo(`Searching for branch that contains commit ${latestTagCommit}...`);
const branchWithLatestTag = exec(`git branch -r --contains ${latestTagCommit}`).stdout.split('/')[1];
let latestVersion = '';
if (branchWithLatestTag.indexOf('-stable') !== -1) {
latestVersion = branchWithLatestTag.slice(0, branchWithLatestTag.indexOf('-stable'));
}
-if (!CI_PULL_REQUEST && CIRCLE_PROJECT_USERNAME === 'facebook') {
- echo(`Building branch ${version}, preparing to push to gh-pages`);
- // if code is running in a branch in CI, commit changes to gh-pages branch
- cd('build');
- rm('-rf', 'react-native-gh-pages');
+echo(`Building static website based on the ${version === 'next' ? 'master' : version} branch, preparing to push assets to GitHub Pages via the 'gh-pages' branch)...`);
+// if code is running in a branch in CI, commit changes to gh-pages branch
+cd('build');
+rm('-rf', 'react-native-gh-pages');
- if (exec(`git clone ${remoteBranch} react-native-gh-pages`).code !== 0) {
- echo('Error: Git clone failed');
- exit(1);
- }
+if (exec(`git clone ${remoteBranch} react-native-gh-pages`).code !== 0) {
+ echo('Error: Git clone failed');
+ exit(1);
+}
+
+cd('react-native-gh-pages');
+
+if (exec('git checkout origin/gh-pages').code +
+ exec('git checkout -b gh-pages').code +
+ exec('git branch --set-upstream-to=origin/gh-pages').code !== 0
+ ) {
+ echo('Error: Git checkout gh-pages failed');
+ exit(1);
+}
+cd('releases');
+let releasesFolders = ls('-d', '*');
+cd('..');
+let versions = releasesFolders.filter(name => name !== 'next');
+if (version !== 'next' && versions.indexOf(version) === -1) {
+ versions.push(version);
+}
- cd('react-native-gh-pages');
+versions.sort(semverCmp).reverse();
- if (exec('git checkout origin/gh-pages').code +
- exec('git checkout -b gh-pages').code +
- exec('git branch --set-upstream-to=origin/gh-pages').code !== 0
- ) {
- echo('Error: Git checkout gh-pages failed');
+// generate to releases/XX when branch name indicates that it is some sort of release
+if (version) {
+ echo(`------------ DEPLOYING /releases/${version}`);
+ rm('-rf', `releases/${version}`);
+ mkdir('-p', `releases/${version}`);
+ cd('../..');
+ if (exec(`RN_DEPLOYMENT_PATH=releases/${version} RN_VERSION=${version} RN_LATEST_VERSION=${latestVersion} \
+ RN_AVAILABLE_DOCS_VERSIONS=${versions.join(',')} node server/generate.js`).code !== 0) {
+ echo('Error: Generating HTML failed');
exit(1);
}
- cd('releases');
- let releasesFolders = ls('-d', '*');
- cd('..');
- let versions = releasesFolders.filter(name => name !== 'next');
- if (version !== 'next' && versions.indexOf(version) === -1) {
- versions.push(version);
+ cd('build/react-native-gh-pages');
+ // blog, showcase, support are copied separately
+ let toCopy = ls('../react-native')
+ .filter(file => (file !== 'blog') && (file !== 'showcase.html') && (file !== 'support.html'))
+ .map(file => `../react-native/${file}`);
+ cp('-R', toCopy, `releases/${version}`);
+ // versions.html is located in root of website and updated with every release
+ cp('../react-native/versions.html', '.');
+}
+// generate to root folder when commit is tagged as latest, i.e. stable and needs to be shown at the root of repo
+if (currentCommit === latestTagCommit) {
+ echo('------------ DEPLOYING latest');
+ // leave only releases and blog folder
+ rm('-rf', ls('*').filter(name => (name !== 'releases') && (name !== 'blog') && (name !== 'showcase.html') && (name !== 'support.html')));
+ cd('../..');
+ if (exec(`RN_VERSION=${version} RN_LATEST_VERSION=${latestVersion} \
+ RN_AVAILABLE_DOCS_VERSIONS=${versions} node server/generate.js`).code !== 0) {
+ echo('Error: Generating HTML failed');
+ exit(1);
}
-
- versions.sort(semverCmp).reverse();
-
- // generate to releases/XX when branch name indicates that it is some sort of release
- if (version) {
- echo(`------------ DEPLOYING /releases/${version}`);
- rm('-rf', `releases/${version}`);
- mkdir('-p', `releases/${version}`);
- cd('../..');
- if (exec(`RN_DEPLOYMENT_PATH=releases/${version} RN_VERSION=${version} RN_LATEST_VERSION=${latestVersion} \
- RN_AVAILABLE_DOCS_VERSIONS=${versions.join(',')} node server/generate.js`).code !== 0) {
- echo('Error: Generating HTML failed');
+ cd('build/react-native-gh-pages');
+ // blog, showcase, support are copied separately
+ let toCopy = ls('../react-native')
+ .filter(file => (file !== 'blog') && (file !== 'showcase.html') && (file !== 'support.html'))
+ .map(file => `../react-native/${file}`);
+ cp('-R', toCopy, '.');
+}
+// blog, showcase, support are versionless, we always build them in root file
+if (areVersionlessSectionsToBeDeployed) {
+ echo('------------ COPYING blog');
+ rm('-rf', 'blog');
+ cp('-R', '../react-native/blog', '.');
+ echo('------------ COPYING showcase');
+ cp('../react-native/showcase.html', '.');
+ echo('------------ COPYING support');
+ cp('../react-native/support.html', '.');
+}
+if (currentCommit === latestTagCommit || version) {
+ exec('git status');
+ exec('git add -A .');
+ if (exec('git diff-index --quiet HEAD --').code !== 0) {
+ if (exec(`git commit -m "Updated docs for ${version}"`).code !== 0) {
+ echo('Error: Git commit gh-pages failed');
exit(1);
}
- cd('build/react-native-gh-pages');
- // blog, showcase, support are copied separately
- let toCopy = ls('../react-native')
- .filter(file => (file !== 'blog') && (file !== 'showcase.html') && (file !== 'support.html'))
- .map(file => `../react-native/${file}`);
- cp('-R', toCopy, `releases/${version}`);
- // versions.html is located in root of website and updated with every release
- cp('../react-native/versions.html', '.');
- }
- // generate to root folder when commit is tagged as latest, i.e. stable and needs to be shown at the root of repo
- if (currentCommit === latestTagCommit) {
- echo('------------ DEPLOYING latest');
- // leave only releases and blog folder
- rm('-rf', ls('*').filter(name => (name !== 'releases') && (name !== 'blog') && (name !== 'showcase.html') && (name !== 'support.html')));
- cd('../..');
- if (exec(`RN_VERSION=${version} RN_LATEST_VERSION=${latestVersion} \
- RN_AVAILABLE_DOCS_VERSIONS=${versions} node server/generate.js`).code !== 0) {
- echo('Error: Generating HTML failed');
+ if (exec('git push origin gh-pages').code !== 0) {
+ echo('Error: Git push gh-pages failed');
exit(1);
}
- cd('build/react-native-gh-pages');
- // blog, showcase, support are copied separately
- let toCopy = ls('../react-native')
- .filter(file => (file !== 'blog') && (file !== 'showcase.html') && (file !== 'support.html'))
- .map(file => `../react-native/${file}`);
- cp('-R', toCopy, '.');
- }
- // blog, showcase, support are versionless, we always build them in root file
- if (areVersionlessSectionsToBeDeployed) {
- echo('------------ COPYING blog');
- rm('-rf', 'blog');
- cp('-R', '../react-native/blog', '.');
- echo('------------ COPYING showcase');
- cp('../react-native/showcase.html', '.');
- echo('------------ COPYING support');
- cp('../react-native/support.html', '.');
- }
- if (currentCommit === latestTagCommit || version) {
- exec('git status');
- exec('git add -A .');
- if (exec('git diff-index --quiet HEAD --').code !== 0) {
- if (exec(`git commit -m "Updated docs for ${version}"`).code !== 0) {
- echo('Error: Git commit gh-pages failed');
- exit(1);
- }
- if (exec('git push origin gh-pages').code !== 0) {
- echo('Error: Git push gh-pages failed');
- exit(1);
- }
- }
- echo('------------ gh-pages updated');
}
-
+ echo('------------ gh-pages updated');
}
From 45185947ee5f1672fb00765a8b32a7100fd0c1bd Mon Sep 17 00:00:00 2001
From: Douglas
Date: Thu, 9 Nov 2017 13:41:29 -0800
Subject: [PATCH 16/50] Fix tvOS compile issues; enable TVEventHandler in Modal
(fix #15389)
Summary:
**Motivation**
Fix an issue (#15389) where `TVEventHandler` would not work when a modal was visible. The solution adds the gesture recognizers from the native `RCTTVRemoteHandler` to the native modal view (except for the menu button recognizer, which still needs special handling in modals). This PR also fixes some breakages in compiling React Native for tvOS.
**Test plan**
Compilation fixes should enable tvOS compile test to pass in Travis CI.
The modal fix can be tested with the following component, modified from the original source in #15389 .
``` javascript
import React, { Component } from 'react';
import ReactNative from 'ReactNative';
import {
Text,
View,
StyleSheet,
TouchableHighlight,
TVEventHandler,
Modal,
} from 'react-native';
export default class Events extends Component {
constructor(props) {
super(props);
this.state = {
modalVisible: false,
};
this._tvEventHandler = new TVEventHandler();
}
_enableTVEventHandler() {
this._tvEventHandler.enable(this, (cmp, evt) => {
const myTag = ReactNative.findNodeHandle(cmp);
console.log('Event.js TVEventHandler: ', evt.eventType);
// if (evt.eventType !== 'blur' && evt.eventType !== 'focus') {
// console.log('Event.js TVEventHandler: ', evt.eventType);
// }
});
}
_disableTVEventHandler() {
if (this._tvEventHandler) {
this._tvEventHandler.disable();
delete this._tvEventHandler;
}
}
componentDidMount() {
this._enableTVEventHandler();
}
componentWillUnmount() {
this._disableTVEventHandler();
}
_renderRow() {
return (
{
Array.from({ length: 7 }).map((_, index) => {
return (
{ this.setState({ modalVisible: !this.state.modalVisible }); }}
>
{ index }
);
})
}
);
}
onTVEvent(cmp, evt) {
console.log('Modal.js TVEventHandler: ', evt.eventType);
}
hideModal() {
this.setState({
modalVisible: false
});
}
render() {
return (
this.hideModal()}>
{ this._renderRow() }
{ this._renderRow() }
{ this._renderRow() }
{ this._renderRow() }
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'darkslategrey',
},
row: {
flexDirection: 'row',
padding: 30,
},
item: {
width: 200,
height: 100,
borderColor: 'cyan',
borderWidth: 2,
margin: 30,
alignItems: 'center',
justifyContent: 'center',
},
itemText: {
fontSize: 40,
color: 'cyan',
},
modal: {
flex: 1,
backgroundColor: 'steelblue',
},
});
```
**Release Notes**
After this change, the `onRequestClose` property will be required for a `Modal` in Apple TV.
Closes https://github.com/facebook/react-native/pull/16076
Differential Revision: D6288801
Pulled By: hramos
fbshipit-source-id: 446ae94a060387324aa9e528bd93cdabc9b5b37f
---
.../Text/RCTText.xcodeproj/project.pbxproj | 1 +
RNTester/RNTester.xcodeproj/project.pbxproj | 97 +++++++++++++------
.../AppIcon.appiconset/Contents.json | 5 +
RNTester/js/ListExampleShared.js | 3 +
RNTester/js/ModalExample.js | 31 ++++--
React/Base/RCTRootView.m | 4 +-
React/Base/RCTTVRemoteHandler.h | 20 +++-
React/Base/RCTTVRemoteHandler.m | 91 +++++++++++------
React/React.xcodeproj/project.pbxproj | 10 +-
React/Views/RCTModalHostView.h | 2 +
React/Views/RCTModalHostView.m | 10 ++
.../ios/HelloWorld.xcodeproj/project.pbxproj | 70 +++++++++++--
12 files changed, 266 insertions(+), 78 deletions(-)
diff --git a/Libraries/Text/RCTText.xcodeproj/project.pbxproj b/Libraries/Text/RCTText.xcodeproj/project.pbxproj
index cb8b92e4f38c7a..0065b050984e6b 100644
--- a/Libraries/Text/RCTText.xcodeproj/project.pbxproj
+++ b/Libraries/Text/RCTText.xcodeproj/project.pbxproj
@@ -22,6 +22,7 @@
2D3B5F3A1D9B106F00451313 /* RCTTextFieldManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1362F0FF1B4D51F400E06D8C /* RCTTextFieldManager.m */; };
2D3B5F3B1D9B106F00451313 /* RCTTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 131B6ABD1AF0CD0600FFC3E0 /* RCTTextView.m */; };
2D3B5F3C1D9B106F00451313 /* RCTTextViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 131B6ABF1AF0CD0600FFC3E0 /* RCTTextViewManager.m */; };
+ 2DEAB2901F84BA4300FC6B42 /* RCTFontAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = A85C82991F742AA20036C019 /* RCTFontAttributes.m */; };
58B511CE1A9E6C5C00147676 /* RCTRawTextManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B511C71A9E6C5C00147676 /* RCTRawTextManager.m */; };
58B511CF1A9E6C5C00147676 /* RCTShadowRawText.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B511C91A9E6C5C00147676 /* RCTShadowRawText.m */; };
58B511D01A9E6C5C00147676 /* RCTShadowText.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B511CB1A9E6C5C00147676 /* RCTShadowText.m */; };
diff --git a/RNTester/RNTester.xcodeproj/project.pbxproj b/RNTester/RNTester.xcodeproj/project.pbxproj
index 039f9c656f2436..18510385e40f69 100644
--- a/RNTester/RNTester.xcodeproj/project.pbxproj
+++ b/RNTester/RNTester.xcodeproj/project.pbxproj
@@ -21,7 +21,6 @@
139FDEDB1B0651FB00C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDED91B0651EA00C62182 /* libRCTWebSocket.a */; };
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
- 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
13B6C1A31C34225900D3FAF5 /* RCTURLUtilsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B6C1A21C34225900D3FAF5 /* RCTURLUtilsTests.m */; };
13BCE84F1C9C209600DD7AAD /* RCTComponentPropsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13BCE84E1C9C209600DD7AAD /* RCTComponentPropsTests.m */; };
@@ -59,7 +58,6 @@
27F441EC1BEBE5030039B79C /* FlexibleSizeExampleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 27F441E81BEBE5030039B79C /* FlexibleSizeExampleView.m */; };
2D4624FA1DA2EAC300C74D09 /* RCTLoggingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D299BAE1D33EBFA00FA1057 /* RCTLoggingTests.m */; };
2D4624FB1DA2EAC300C74D09 /* RCTRootViewIntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 27B885551BED29AF00008352 /* RCTRootViewIntegrationTests.m */; };
- 2D4624FC1DA2EAC300C74D09 /* RNTesterIntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB99D0B1BA0340600302749 /* RNTesterIntegrationTests.m */; };
2D4624FD1DA2EAC300C74D09 /* RNTesterSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 143BC5A01B21E45C00462512 /* RNTesterSnapshotTests.m */; };
2D4624FE1DA2EAC300C74D09 /* RCTUIManagerScenarioTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 83636F8E1B53F22C009F943E /* RCTUIManagerScenarioTests.m */; };
2D4625351DA2EBBE00C74D09 /* libRCTTest-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD323CC1DA2DD8B000FE1B8 /* libRCTTest-tvOS.a */; };
@@ -75,12 +73,9 @@
2D4BD8DD1DA2E20D005AC8A8 /* RCTImageUtilTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 144D21231B2204C5006DB32B /* RCTImageUtilTests.m */; };
2D4BD8DE1DA2E20D005AC8A8 /* RCTJSONTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13DB03471B5D2ED500C27245 /* RCTJSONTests.m */; };
2D4BD8DF1DA2E20D005AC8A8 /* RCTMethodArgumentTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13DF61B51B67A45000EDB188 /* RCTMethodArgumentTests.m */; };
- 2D4BD8E01DA2E20D005AC8A8 /* RCTModuleInitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 134CB9291C85A38800265FA6 /* RCTModuleInitTests.m */; };
- 2D4BD8E11DA2E20D005AC8A8 /* RCTModuleInitNotificationRaceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13129DD31C85F87C007D611C /* RCTModuleInitNotificationRaceTests.m */; };
2D4BD8E21DA2E20D005AC8A8 /* RCTModuleMethodTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1393D0371B68CD1300E1B601 /* RCTModuleMethodTests.mm */; };
2D4BD8E31DA2E20D005AC8A8 /* RCTShadowViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 138D6A161B53CD440074A87E /* RCTShadowViewTests.m */; };
2D4BD8E41DA2E20D005AC8A8 /* RCTUIManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1497CFAB1B21F5E400C1F8F2 /* RCTUIManagerTests.m */; };
- 2D4BD8E51DA2E20D005AC8A8 /* RCTComponentPropsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13BCE84E1C9C209600DD7AAD /* RCTComponentPropsTests.m */; };
2D4BD8E61DA2E20D005AC8A8 /* RNTesterUnitTestsBundle.js in Resources */ = {isa = PBXBuildFile; fileRef = 3DD981D51D33C6FB007DC7BE /* RNTesterUnitTestsBundle.js */; };
2D4BD8E71DA2E20D005AC8A8 /* libOCMock.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14D6D7101B220EB3001FB087 /* libOCMock.a */; };
2D66FF8F1ECA406D00F0A767 /* libART.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D66FF651ECA405900F0A767 /* libART.a */; };
@@ -89,7 +84,6 @@
2DD323DC1DA2DDBF000FE1B8 /* FlexibleSizeExampleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 27F441E81BEBE5030039B79C /* FlexibleSizeExampleView.m */; };
2DD323DD1DA2DDBF000FE1B8 /* UpdatePropertiesExampleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 272E6B3C1BEA849E001FCF37 /* UpdatePropertiesExampleView.m */; };
2DD323DE1DA2DDBF000FE1B8 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
- 2DD323DF1DA2DDBF000FE1B8 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
2DD323E01DA2DDBF000FE1B8 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
2DD323E11DA2DDBF000FE1B8 /* legacy_image@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3D2AFAF41D646CF80089D1A3 /* legacy_image@2x.png */; };
2DD323E21DA2DDBF000FE1B8 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB61A68108700A75B9A /* Info.plist */; };
@@ -100,6 +94,18 @@
2DD323E81DA2DE3F000FE1B8 /* libRCTText-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD323D01DA2DD8B000FE1B8 /* libRCTText-tvOS.a */; };
2DD323E91DA2DE3F000FE1B8 /* libRCTWebSocket-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD323D51DA2DD8B000FE1B8 /* libRCTWebSocket-tvOS.a */; };
2DD323EA1DA2DE3F000FE1B8 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD323D91DA2DD8B000FE1B8 /* libReact.a */; };
+ 2DDEF0101F84BF7B00DBDF73 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2DDEF00F1F84BF7B00DBDF73 /* Images.xcassets */; };
+ 2DE7E7FD1FB2A4F3009E225D /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD323B51DA2DD8B000FE1B8 /* libRCTAnimation.a */; };
+ 2DE7E7FE1FB2A4F3009E225D /* libRCTBlob-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5281CA531EEAC9A700AC40CD /* libRCTBlob-tvOS.a */; };
+ 2DE7E7FF1FB2A4F3009E225D /* libRCTImage-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD323BB1DA2DD8B000FE1B8 /* libRCTImage-tvOS.a */; };
+ 2DE7E8001FB2A4F3009E225D /* libRCTLinking-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD323BF1DA2DD8B000FE1B8 /* libRCTLinking-tvOS.a */; };
+ 2DE7E8011FB2A4F3009E225D /* libRCTNetwork-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD323C31DA2DD8B000FE1B8 /* libRCTNetwork-tvOS.a */; };
+ 2DE7E8021FB2A4F3009E225D /* libRCTPushNotification-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D05746C1DE6008900184BB4 /* libRCTPushNotification-tvOS.a */; };
+ 2DE7E8031FB2A4F3009E225D /* libRCTSettings-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD323C81DA2DD8B000FE1B8 /* libRCTSettings-tvOS.a */; };
+ 2DE7E8041FB2A4F3009E225D /* libRCTTest-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD323CC1DA2DD8B000FE1B8 /* libRCTTest-tvOS.a */; };
+ 2DE7E8051FB2A4F3009E225D /* libRCTText-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD323D01DA2DD8B000FE1B8 /* libRCTText-tvOS.a */; };
+ 2DE7E8061FB2A4F3009E225D /* libRCTWebSocket-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD323D51DA2DD8B000FE1B8 /* libRCTWebSocket-tvOS.a */; };
+ 2DE7E8071FB2A4F3009E225D /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DD323D91DA2DD8B000FE1B8 /* libReact.a */; };
3578590A1B28D2CF00341EDB /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 357859011B28D2C500341EDB /* libRCTLinking.a */; };
39AA31A41DC1DFDC000F7EBB /* RCTUnicodeDecodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 39AA31A31DC1DFDC000F7EBB /* RCTUnicodeDecodeTests.m */; };
3D05746D1DE6008900184BB4 /* libRCTPushNotification-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D05746C1DE6008900184BB4 /* libRCTPushNotification-tvOS.a */; };
@@ -210,6 +216,20 @@
remoteGlobalIDString = 2DD3238F1DA2DD8A000FE1B8;
remoteInfo = "RNTester-tvOS";
};
+ 2D609F0C1F84BD7E00D65B08 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 14AADEFF1AC3DB95002390C9 /* React.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = 9936F3131F5F2E4B0010BF04;
+ remoteInfo = privatedata;
+ };
+ 2D609F0E1F84BD7E00D65B08 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 14AADEFF1AC3DB95002390C9 /* React.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = 9936F32F1F5F2E5B0010BF04;
+ remoteInfo = "privatedata-tvOS";
+ };
2D66FF641ECA405900F0A767 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2D66FF5F1ECA405900F0A767 /* ART.xcodeproj */;
@@ -238,13 +258,6 @@
remoteGlobalIDString = 3D383D621EBD27B9005632C8;
remoteInfo = "double-conversion-tvOS";
};
- 2DD323A61DA2DD8B000FE1B8 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = 2DD3238F1DA2DD8A000FE1B8;
- remoteInfo = "RNTester-tvOS";
- };
2DD323B41DA2DD8B000FE1B8 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 13E5019C1D07A502005F35D8 /* RCTAnimation.xcodeproj */;
@@ -454,7 +467,6 @@
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = RNTester/AppDelegate.h; sourceTree = ""; };
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = RNTester/AppDelegate.m; sourceTree = ""; };
13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
- 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = RNTester/Images.xcassets; sourceTree = ""; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = RNTester/Info.plist; sourceTree = ""; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = RNTester/main.m; sourceTree = ""; };
13B6C1A21C34225900D3FAF5 /* RCTURLUtilsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTURLUtilsTests.m; sourceTree = ""; };
@@ -499,6 +511,7 @@
2DD323901DA2DD8A000FE1B8 /* RNTester-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "RNTester-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
2DD323A01DA2DD8B000FE1B8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
2DD323A51DA2DD8B000FE1B8 /* RNTester-tvOSUnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "RNTester-tvOSUnitTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 2DDEF00F1F84BF7B00DBDF73 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = RNTester/Images.xcassets; sourceTree = ""; };
357858F81B28D2C400341EDB /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = ../Libraries/LinkingIOS/RCTLinking.xcodeproj; sourceTree = ""; };
39AA31A31DC1DFDC000F7EBB /* RCTUnicodeDecodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTUnicodeDecodeTests.m; sourceTree = ""; };
3D13F83E1D6F6AE000E69E0E /* RNTesterBundle.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RNTesterBundle.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -602,6 +615,17 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 2DE7E7FD1FB2A4F3009E225D /* libRCTAnimation.a in Frameworks */,
+ 2DE7E7FE1FB2A4F3009E225D /* libRCTBlob-tvOS.a in Frameworks */,
+ 2DE7E7FF1FB2A4F3009E225D /* libRCTImage-tvOS.a in Frameworks */,
+ 2DE7E8001FB2A4F3009E225D /* libRCTLinking-tvOS.a in Frameworks */,
+ 2DE7E8011FB2A4F3009E225D /* libRCTNetwork-tvOS.a in Frameworks */,
+ 2DE7E8021FB2A4F3009E225D /* libRCTPushNotification-tvOS.a in Frameworks */,
+ 2DE7E8031FB2A4F3009E225D /* libRCTSettings-tvOS.a in Frameworks */,
+ 2DE7E8041FB2A4F3009E225D /* libRCTTest-tvOS.a in Frameworks */,
+ 2DE7E8051FB2A4F3009E225D /* libRCTText-tvOS.a in Frameworks */,
+ 2DE7E8061FB2A4F3009E225D /* libRCTWebSocket-tvOS.a in Frameworks */,
+ 2DE7E8071FB2A4F3009E225D /* libReact.a in Frameworks */,
2D4BD8E71DA2E20D005AC8A8 /* libOCMock.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -705,10 +729,10 @@
13B07FAE1A68108700A75B9A /* RNTester */ = {
isa = PBXGroup;
children = (
+ 2DDEF00F1F84BF7B00DBDF73 /* Images.xcassets */,
272E6B3A1BEA846C001FCF37 /* NativeExampleViews */,
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
13B07FB01A68108700A75B9A /* AppDelegate.m */,
- 13B07FB51A68108700A75B9A /* Images.xcassets */,
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
13B07FB71A68108700A75B9A /* main.m */,
1323F18D1C04ABAC0091BED0 /* Supporting Files */,
@@ -806,6 +830,8 @@
2D66FF8C1ECA405900F0A767 /* libthird-party.a */,
3D507F441EBC88B700B56834 /* libdouble-conversion.a */,
2D66FF8E1ECA405900F0A767 /* libdouble-conversion.a */,
+ 2D609F0D1F84BD7E00D65B08 /* libprivatedata.a */,
+ 2D609F0F1F84BD7E00D65B08 /* libprivatedata-tvOS.a */,
);
name = Products;
sourceTree = "";
@@ -870,6 +896,13 @@
path = "RNTester-tvOS";
sourceTree = "";
};
+ 2DE7E7D81FB2A4F3009E225D /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
357858F91B28D2C400341EDB /* Products */ = {
isa = PBXGroup;
children = (
@@ -928,6 +961,7 @@
14D6D6EA1B2205C0001FB087 /* OCMock */,
2DD323911DA2DD8B000FE1B8 /* RNTester-tvOS */,
83CBBA001A601CBA00E9B192 /* Products */,
+ 2DE7E7D81FB2A4F3009E225D /* Frameworks */,
);
indentWidth = 2;
sourceTree = "";
@@ -1060,7 +1094,6 @@
buildRules = (
);
dependencies = (
- 2DD323A71DA2DD8B000FE1B8 /* PBXTargetDependency */,
);
name = "RNTester-tvOSUnitTests";
productName = "RNTester-tvOSUnitTests";
@@ -1275,6 +1308,20 @@
remoteRef = 14DC67F01AB71876001358AB /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
+ 2D609F0D1F84BD7E00D65B08 /* libprivatedata.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = libprivatedata.a;
+ remoteRef = 2D609F0C1F84BD7E00D65B08 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ 2D609F0F1F84BD7E00D65B08 /* libprivatedata-tvOS.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = "libprivatedata-tvOS.a";
+ remoteRef = 2D609F0E1F84BD7E00D65B08 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
2D66FF651ECA405900F0A767 /* libART.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
@@ -1500,8 +1547,8 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
3D56F9F11D6F6E9B00F53A06 /* RNTesterBundle.bundle in Resources */,
+ 2DDEF0101F84BF7B00DBDF73 /* Images.xcassets in Resources */,
3D2AFAF51D646CF80089D1A3 /* legacy_image@2x.png in Resources */,
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,
);
@@ -1525,7 +1572,6 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 2DD323DF1DA2DDBF000FE1B8 /* Images.xcassets in Resources */,
2DD323E11DA2DDBF000FE1B8 /* legacy_image@2x.png in Resources */,
2DD323E21DA2DDBF000FE1B8 /* Info.plist in Resources */,
);
@@ -1641,7 +1687,6 @@
buildActionMask = 2147483647;
files = (
C654F17E1EB34D24000B7A9A /* RNTesterTestModule.m in Sources */,
- 2D4624FC1DA2EAC300C74D09 /* RNTesterIntegrationTests.m in Sources */,
2D4624FA1DA2EAC300C74D09 /* RCTLoggingTests.m in Sources */,
2D4624FE1DA2EAC300C74D09 /* RCTUIManagerScenarioTests.m in Sources */,
2D4624FD1DA2EAC300C74D09 /* RNTesterSnapshotTests.m in Sources */,
@@ -1669,10 +1714,8 @@
2D4BD8D41DA2E20D005AC8A8 /* RCTAllocationTests.m in Sources */,
2D4BD8DA1DA2E20D005AC8A8 /* RCTGzipTests.m in Sources */,
2D4BD8DB1DA2E20D005AC8A8 /* RCTImageLoaderHelpers.m in Sources */,
- 2D4BD8E51DA2E20D005AC8A8 /* RCTComponentPropsTests.m in Sources */,
2D4BD8D71DA2E20D005AC8A8 /* RCTConvert_NSURLTests.m in Sources */,
2D4BD8E21DA2E20D005AC8A8 /* RCTModuleMethodTests.mm in Sources */,
- 2D4BD8E11DA2E20D005AC8A8 /* RCTModuleInitNotificationRaceTests.m in Sources */,
2D4BD8DF1DA2E20D005AC8A8 /* RCTMethodArgumentTests.m in Sources */,
2D4BD8D31DA2E20D005AC8A8 /* RCTBundleURLProviderTests.m in Sources */,
2D4BD8D21DA2E20D005AC8A8 /* RCTURLUtilsTests.m in Sources */,
@@ -1682,7 +1725,6 @@
2D4BD8D81DA2E20D005AC8A8 /* RCTFontTests.m in Sources */,
2D4BD8DD1DA2E20D005AC8A8 /* RCTImageUtilTests.m in Sources */,
2D4BD8E41DA2E20D005AC8A8 /* RCTUIManagerTests.m in Sources */,
- 2D4BD8E01DA2E20D005AC8A8 /* RCTModuleInitTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1706,11 +1748,6 @@
target = 2DD3238F1DA2DD8A000FE1B8 /* RNTester-tvOS */;
targetProxy = 2D4624C31DA2EA6900C74D09 /* PBXContainerItemProxy */;
};
- 2DD323A71DA2DD8B000FE1B8 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = 2DD3238F1DA2DD8A000FE1B8 /* RNTester-tvOS */;
- targetProxy = 2DD323A61DA2DD8B000FE1B8 /* PBXContainerItemProxy */;
- };
3D13F84C1D6F6B5F00E69E0E /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 3D13F83D1D6F6AE000E69E0E /* RNTesterBundle */;
@@ -1775,6 +1812,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = "$(SRCROOT)/RNTester/Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 9.3;
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = com.facebook.react.uiapp;
PRODUCT_NAME = RNTester;
@@ -1788,6 +1826,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEVELOPMENT_TEAM = V9WTTPBFK9;
INFOPLIST_FILE = "$(SRCROOT)/RNTester/Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 9.3;
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = com.facebook.react.uiapp;
PRODUCT_NAME = RNTester;
@@ -1896,7 +1935,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = appletvos;
TARGETED_DEVICE_FAMILY = 3;
- TVOS_DEPLOYMENT_TARGET = 9.2;
+ TVOS_DEPLOYMENT_TARGET = 10.2;
};
name = Debug;
};
@@ -1916,7 +1955,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = appletvos;
TARGETED_DEVICE_FAMILY = 3;
- TVOS_DEPLOYMENT_TARGET = 9.2;
+ TVOS_DEPLOYMENT_TARGET = 10.2;
};
name = Release;
};
diff --git a/RNTester/RNTester/Images.xcassets/AppIcon.appiconset/Contents.json b/RNTester/RNTester/Images.xcassets/AppIcon.appiconset/Contents.json
index 7accb5223dd5f8..2186a876cf87c8 100644
--- a/RNTester/RNTester/Images.xcassets/AppIcon.appiconset/Contents.json
+++ b/RNTester/RNTester/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -45,6 +45,11 @@
"idiom" : "iphone",
"filename" : "Icon-60@3x.png",
"scale" : "3x"
+ },
+ {
+ "idiom" : "ios-marketing",
+ "size" : "1024x1024",
+ "scale" : "1x"
}
],
"info" : {
diff --git a/RNTester/js/ListExampleShared.js b/RNTester/js/ListExampleShared.js
index cae8519f0aca74..d9569efb0d1c97 100644
--- a/RNTester/js/ListExampleShared.js
+++ b/RNTester/js/ListExampleShared.js
@@ -201,6 +201,9 @@ function pressItem(context: Object, key: string) {
}
function renderSmallSwitchOption(context: Object, key: string) {
+ if(Platform.isTVOS) {
+ return null;
+ }
return (
{key}:
diff --git a/RNTester/js/ModalExample.js b/RNTester/js/ModalExample.js
index c57ef54edb67d1..e0c4a55b22c5cb 100644
--- a/RNTester/js/ModalExample.js
+++ b/RNTester/js/ModalExample.js
@@ -16,6 +16,7 @@ var ReactNative = require('react-native');
var {
Modal,
Picker,
+ Platform,
StyleSheet,
Switch,
Text,
@@ -91,6 +92,15 @@ class ModalExample extends React.Component<{}, $FlowFixMeState> {
this.setState({transparent: !this.state.transparent});
};
+ renderSwitch() {
+ if (Platform.isTVOS) {
+ return null;
+ }
+ return (
+
+ );
+ }
+
render() {
var modalBackgroundStyle = {
backgroundColor: this.state.transparent ? 'rgba(0, 0, 0, 0.5)' : '#f5fcff',
@@ -140,9 +150,21 @@ class ModalExample extends React.Component<{}, $FlowFixMeState> {
Transparent
-
+ {this.renderSwitch()}
-
+ {this.renderPickers()}
+
+
+ );
+ }
+ renderPickers() {
+ if (Platform.isTVOS) {
+ return null;
+ }
+ return (
+ Presentation style {
-
-
);
}
}
+
exports.examples = [
{
title: 'Modal Presentation',
diff --git a/React/Base/RCTRootView.m b/React/Base/RCTRootView.m
index 980e9e01ee8fda..4a5e53c650ce51 100644
--- a/React/Base/RCTRootView.m
+++ b/React/Base/RCTRootView.m
@@ -91,8 +91,8 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge
#if TARGET_OS_TV
self.tvRemoteHandler = [RCTTVRemoteHandler new];
- for (UIGestureRecognizer *gr in self.tvRemoteHandler.tvRemoteGestureRecognizers) {
- [self addGestureRecognizer:gr];
+ for (NSString *key in [self.tvRemoteHandler.tvRemoteGestureRecognizers allKeys]) {
+ [self addGestureRecognizer:self.tvRemoteHandler.tvRemoteGestureRecognizers[key]];
}
#endif
diff --git a/React/Base/RCTTVRemoteHandler.h b/React/Base/RCTTVRemoteHandler.h
index 51492a4c9fbb69..aedd9aefe0a93c 100644
--- a/React/Base/RCTTVRemoteHandler.h
+++ b/React/Base/RCTTVRemoteHandler.h
@@ -9,8 +9,26 @@
#import
+
+extern NSString *const RCTTVRemoteEventMenu;
+extern NSString *const RCTTVRemoteEventPlayPause;
+extern NSString *const RCTTVRemoteEventSelect;
+
+extern NSString *const RCTTVRemoteEventLongPlayPause;
+extern NSString *const RCTTVRemoteEventLongSelect;
+
+extern NSString *const RCTTVRemoteEventLeft;
+extern NSString *const RCTTVRemoteEventRight;
+extern NSString *const RCTTVRemoteEventUp;
+extern NSString *const RCTTVRemoteEventDown;
+
+extern NSString *const RCTTVRemoteEventSwipeLeft;
+extern NSString *const RCTTVRemoteEventSwipeRight;
+extern NSString *const RCTTVRemoteEventSwipeUp;
+extern NSString *const RCTTVRemoteEventSwipeDown;
+
@interface RCTTVRemoteHandler : NSObject
-@property (nonatomic, copy, readonly) NSArray *tvRemoteGestureRecognizers;
+@property (nonatomic, copy, readonly) NSDictionary *tvRemoteGestureRecognizers;
@end
diff --git a/React/Base/RCTTVRemoteHandler.m b/React/Base/RCTTVRemoteHandler.m
index 12d70809d25f23..8b39e8eddd2529 100644
--- a/React/Base/RCTTVRemoteHandler.m
+++ b/React/Base/RCTTVRemoteHandler.m
@@ -26,71 +26,102 @@
#import "RCTDevMenu.h"
#endif
+NSString *const RCTTVRemoteEventMenu = @"menu";
+NSString *const RCTTVRemoteEventPlayPause = @"playPause";
+NSString *const RCTTVRemoteEventSelect = @"select";
+
+NSString *const RCTTVRemoteEventLongPlayPause = @"longPlayPause";
+NSString *const RCTTVRemoteEventLongSelect = @"longSelect";
+
+NSString *const RCTTVRemoteEventLeft = @"left";
+NSString *const RCTTVRemoteEventRight = @"right";
+NSString *const RCTTVRemoteEventUp = @"up";
+NSString *const RCTTVRemoteEventDown = @"down";
+
+NSString *const RCTTVRemoteEventSwipeLeft = @"swipeLeft";
+NSString *const RCTTVRemoteEventSwipeRight = @"swipeRight";
+NSString *const RCTTVRemoteEventSwipeUp = @"swipeUp";
+NSString *const RCTTVRemoteEventSwipeDown = @"swipeDown";
+
+
@implementation RCTTVRemoteHandler {
- NSMutableArray *_tvRemoteGestureRecognizers;
+ NSMutableDictionary *_tvRemoteGestureRecognizers;
}
- (instancetype)init
{
if ((self = [super init])) {
- _tvRemoteGestureRecognizers = [NSMutableArray array];
+ _tvRemoteGestureRecognizers = [NSMutableDictionary dictionary];
// Recognizers for Apple TV remote buttons
// Play/Pause
[self addTapGestureRecognizerWithSelector:@selector(playPausePressed:)
- pressType:UIPressTypePlayPause];
+ pressType:UIPressTypePlayPause
+ name:RCTTVRemoteEventPlayPause];
// Menu
[self addTapGestureRecognizerWithSelector:@selector(menuPressed:)
- pressType:UIPressTypeMenu];
+ pressType:UIPressTypeMenu
+ name:RCTTVRemoteEventMenu];
// Select
[self addTapGestureRecognizerWithSelector:@selector(selectPressed:)
- pressType:UIPressTypeSelect];
+ pressType:UIPressTypeSelect
+ name:RCTTVRemoteEventSelect];
// Up
[self addTapGestureRecognizerWithSelector:@selector(swipedUp:)
- pressType:UIPressTypeUpArrow];
+ pressType:UIPressTypeUpArrow
+ name:RCTTVRemoteEventUp];
// Down
[self addTapGestureRecognizerWithSelector:@selector(swipedDown:)
- pressType:UIPressTypeDownArrow];
+ pressType:UIPressTypeDownArrow
+ name:RCTTVRemoteEventDown];
// Left
[self addTapGestureRecognizerWithSelector:@selector(swipedLeft:)
- pressType:UIPressTypeLeftArrow];
+ pressType:UIPressTypeLeftArrow
+ name:RCTTVRemoteEventLeft];
// Right
[self addTapGestureRecognizerWithSelector:@selector(swipedRight:)
- pressType:UIPressTypeRightArrow];
+ pressType:UIPressTypeRightArrow
+ name:RCTTVRemoteEventRight];
// Recognizers for long button presses
// We don't intercept long menu press -- that's used by the system to go to the home screen
[self addLongPressGestureRecognizerWithSelector:@selector(longPlayPausePressed:)
- pressType:UIPressTypePlayPause];
+ pressType:UIPressTypePlayPause
+ name:RCTTVRemoteEventLongPlayPause];
[self addLongPressGestureRecognizerWithSelector:@selector(longSelectPressed:)
- pressType:UIPressTypeSelect];
+ pressType:UIPressTypeSelect
+ name:RCTTVRemoteEventLongSelect];
// Recognizers for Apple TV remote trackpad swipes
// Up
[self addSwipeGestureRecognizerWithSelector:@selector(swipedUp:)
- direction:UISwipeGestureRecognizerDirectionUp];
+ direction:UISwipeGestureRecognizerDirectionUp
+ name:RCTTVRemoteEventSwipeUp];
// Down
[self addSwipeGestureRecognizerWithSelector:@selector(swipedDown:)
- direction:UISwipeGestureRecognizerDirectionDown];
+ direction:UISwipeGestureRecognizerDirectionDown
+ name:RCTTVRemoteEventSwipeDown];
// Left
[self addSwipeGestureRecognizerWithSelector:@selector(swipedLeft:)
- direction:UISwipeGestureRecognizerDirectionLeft];
+ direction:UISwipeGestureRecognizerDirectionLeft
+ name:RCTTVRemoteEventSwipeLeft];
// Right
[self addSwipeGestureRecognizerWithSelector:@selector(swipedRight:)
- direction:UISwipeGestureRecognizerDirectionRight];
+ direction:UISwipeGestureRecognizerDirectionRight
+ name:RCTTVRemoteEventSwipeRight];
}
@@ -99,22 +130,22 @@ - (instancetype)init
- (void)playPausePressed:(UIGestureRecognizer *)r
{
- [self sendAppleTVEvent:@"playPause" toView:r.view];
+ [self sendAppleTVEvent:RCTTVRemoteEventPlayPause toView:r.view];
}
- (void)menuPressed:(UIGestureRecognizer *)r
{
- [self sendAppleTVEvent:@"menu" toView:r.view];
+ [self sendAppleTVEvent:RCTTVRemoteEventMenu toView:r.view];
}
- (void)selectPressed:(UIGestureRecognizer *)r
{
- [self sendAppleTVEvent:@"select" toView:r.view];
+ [self sendAppleTVEvent:RCTTVRemoteEventSelect toView:r.view];
}
- (void)longPlayPausePressed:(UIGestureRecognizer *)r
{
- [self sendAppleTVEvent:@"longPlayPause" toView:r.view];
+ [self sendAppleTVEvent:RCTTVRemoteEventLongPlayPause toView:r.view];
#if __has_include("RCTDevMenu.h") && RCT_DEV
// If shake to show is enabled on device, use long play/pause event to show dev menu
@@ -124,53 +155,53 @@ - (void)longPlayPausePressed:(UIGestureRecognizer *)r
- (void)longSelectPressed:(UIGestureRecognizer *)r
{
- [self sendAppleTVEvent:@"longSelect" toView:r.view];
+ [self sendAppleTVEvent:RCTTVRemoteEventLongSelect toView:r.view];
}
- (void)swipedUp:(UIGestureRecognizer *)r
{
- [self sendAppleTVEvent:@"up" toView:r.view];
+ [self sendAppleTVEvent:RCTTVRemoteEventUp toView:r.view];
}
- (void)swipedDown:(UIGestureRecognizer *)r
{
- [self sendAppleTVEvent:@"down" toView:r.view];
+ [self sendAppleTVEvent:RCTTVRemoteEventDown toView:r.view];
}
- (void)swipedLeft:(UIGestureRecognizer *)r
{
- [self sendAppleTVEvent:@"left" toView:r.view];
+ [self sendAppleTVEvent:RCTTVRemoteEventLeft toView:r.view];
}
- (void)swipedRight:(UIGestureRecognizer *)r
{
- [self sendAppleTVEvent:@"right" toView:r.view];
+ [self sendAppleTVEvent:RCTTVRemoteEventRight toView:r.view];
}
#pragma mark -
-- (void)addLongPressGestureRecognizerWithSelector:(nonnull SEL)selector pressType:(UIPressType)pressType
+- (void)addLongPressGestureRecognizerWithSelector:(nonnull SEL)selector pressType:(UIPressType)pressType name:(NSString *)name
{
UILongPressGestureRecognizer *recognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:selector];
recognizer.allowedPressTypes = @[@(pressType)];
- [_tvRemoteGestureRecognizers addObject:recognizer];
+ _tvRemoteGestureRecognizers[name] = recognizer;
}
-- (void)addTapGestureRecognizerWithSelector:(nonnull SEL)selector pressType:(UIPressType)pressType
+- (void)addTapGestureRecognizerWithSelector:(nonnull SEL)selector pressType:(UIPressType)pressType name:(NSString *)name
{
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:selector];
recognizer.allowedPressTypes = @[@(pressType)];
- [_tvRemoteGestureRecognizers addObject:recognizer];
+ _tvRemoteGestureRecognizers[name] = recognizer;
}
-- (void)addSwipeGestureRecognizerWithSelector:(nonnull SEL)selector direction:(UISwipeGestureRecognizerDirection)direction
+- (void)addSwipeGestureRecognizerWithSelector:(nonnull SEL)selector direction:(UISwipeGestureRecognizerDirection)direction name:(NSString *)name
{
UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:selector];
recognizer.direction = direction;
- [_tvRemoteGestureRecognizers addObject:recognizer];
+ _tvRemoteGestureRecognizers[name] = recognizer;
}
- (void)sendAppleTVEvent:(NSString *)eventType toView:(__unused UIView *)v
diff --git a/React/React.xcodeproj/project.pbxproj b/React/React.xcodeproj/project.pbxproj
index 0c7f8e3c2f2559..b64ab270c76787 100644
--- a/React/React.xcodeproj/project.pbxproj
+++ b/React/React.xcodeproj/project.pbxproj
@@ -263,6 +263,10 @@
27595AD61E575C7800CCE2B1 /* Platform.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D21E03699D0018521A /* Platform.h */; };
27595AD71E575C7800CCE2B1 /* SampleCxxModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D41E03699D0018521A /* SampleCxxModule.h */; };
27595AD81E575C7800CCE2B1 /* SystraceSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D51E03699D0018521A /* SystraceSection.h */; };
+ 2D16E68E1FA4FD3900B85C8A /* RCTTVNavigationEventEmitter.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D0B842D1EC0B51200B2BD8E /* RCTTVNavigationEventEmitter.h */; };
+ 2D1D83CD1F74E2CE00615550 /* libprivatedata-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9936F32F1F5F2E5B0010BF04 /* libprivatedata-tvOS.a */; };
+ 2D1D83CE1F74E2DA00615550 /* libdouble-conversion.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D383D621EBD27B9005632C8 /* libdouble-conversion.a */; };
+ 2D1D83EF1F74E76C00615550 /* RCTModalManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 91076A871F743AB00081B4FA /* RCTModalManager.m */; };
2D3B5E931D9B087300451313 /* RCTErrorInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 3EDCA8A41D3591E700450C31 /* RCTErrorInfo.m */; };
2D3B5E941D9B087900451313 /* RCTBundleURLProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 68EFE4ED1CF6EB3900A1DE13 /* RCTBundleURLProvider.m */; };
2D3B5E951D9B087C00451313 /* RCTAssert.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA4B1A601E3B00E9B192 /* RCTAssert.m */; };
@@ -520,7 +524,6 @@
3D383D6D1EBD2940005632C8 /* libdouble-conversion.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139D7E881E25C6D100323FB7 /* libdouble-conversion.a */; };
3D383D6E1EBD2940005632C8 /* libjschelpers.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D3CD90B1DE5FBD600167DC4 /* libjschelpers.a */; };
3D383D6F1EBD2940005632C8 /* libthird-party.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139D7ECE1E25DB7D00323FB7 /* libthird-party.a */; };
- 3D383D701EBD2949005632C8 /* libdouble-conversion.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D383D621EBD27B9005632C8 /* libdouble-conversion.a */; };
3D383D711EBD2949005632C8 /* libjschelpers.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D3CD9181DE5FBD800167DC4 /* libjschelpers.a */; };
3D383D721EBD2949005632C8 /* libthird-party.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D383D3C1EBD27B6005632C8 /* libthird-party.a */; };
3D3C08891DE342FB00C268FA /* libyoga.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D3C059A1DE3340900C268FA /* libyoga.a */; };
@@ -1299,6 +1302,7 @@
dstPath = include/React;
dstSubfolderSpec = 16;
files = (
+ 2D16E68E1FA4FD3900B85C8A /* RCTTVNavigationEventEmitter.h in Copy Headers */,
59500D481F71C67600B122B7 /* RCTUIManagerUtils.h in Copy Headers */,
3D0E37901F1CC5E100DCAC9F /* RCTWebSocketModule.h in Copy Headers */,
5960C1BF1F0804F50066FD5B /* RCTLayoutAnimation.h in Copy Headers */,
@@ -2210,7 +2214,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 3D383D701EBD2949005632C8 /* libdouble-conversion.a in Frameworks */,
+ 2D1D83CE1F74E2DA00615550 /* libdouble-conversion.a in Frameworks */,
+ 2D1D83CD1F74E2CE00615550 /* libprivatedata-tvOS.a in Frameworks */,
3D383D711EBD2949005632C8 /* libjschelpers.a in Frameworks */,
3D383D721EBD2949005632C8 /* libthird-party.a in Frameworks */,
3D8ED92C1E5B120100D83D20 /* libcxxreact.a in Frameworks */,
@@ -3997,6 +4002,7 @@
2D3B5EC61D9B095000451313 /* RCTProfileTrampoline-x86_64.S in Sources */,
2D3B5EA61D9B08CA00451313 /* RCTTouchEvent.m in Sources */,
2D8C2E331DA40441000EE098 /* RCTMultipartStreamReader.m in Sources */,
+ 2D1D83EF1F74E76C00615550 /* RCTModalManager.m in Sources */,
2D3B5EF01D9B09E300451313 /* RCTWrapperViewController.m in Sources */,
2D3B5EEC1D9B09D400451313 /* RCTTabBarItemManager.m in Sources */,
2D3B5EB01D9B08FE00451313 /* RCTAlertManager.m in Sources */,
diff --git a/React/Views/RCTModalHostView.h b/React/Views/RCTModalHostView.h
index 40b5a35e2e8aac..e638df3246bace 100644
--- a/React/Views/RCTModalHostView.h
+++ b/React/Views/RCTModalHostView.h
@@ -15,6 +15,7 @@
@class RCTBridge;
@class RCTModalHostViewController;
+@class RCTTVRemoteHandler;
@protocol RCTModalHostViewInteractor;
@@ -35,6 +36,7 @@
#if TARGET_OS_TV
@property (nonatomic, copy) RCTDirectEventBlock onRequestClose;
+@property (nonatomic, strong) RCTTVRemoteHandler *tvRemoteHandler;
#endif
- (instancetype)initWithBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER;
diff --git a/React/Views/RCTModalHostView.m b/React/Views/RCTModalHostView.m
index a42c23a437163f..50f44697e92e20 100644
--- a/React/Views/RCTModalHostView.m
+++ b/React/Views/RCTModalHostView.m
@@ -18,6 +18,7 @@
#import "RCTUIManager.h"
#import "RCTUtils.h"
#import "UIView+React.h"
+#import "RCTTVRemoteHandler.h"
@implementation RCTModalHostView
{
@@ -49,6 +50,7 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge
#if TARGET_OS_TV
_menuButtonGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(menuButtonPressed:)];
_menuButtonGestureRecognizer.allowedPressTypes = @[@(UIPressTypeMenu)];
+ self.tvRemoteHandler = [RCTTVRemoteHandler new];
#endif
_isPresented = NO;
@@ -118,6 +120,11 @@ - (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex
[super insertReactSubview:subview atIndex:atIndex];
[_touchHandler attachToView:subview];
#if TARGET_OS_TV
+ for (NSString *key in [self.tvRemoteHandler.tvRemoteGestureRecognizers allKeys]) {
+ if (![key isEqualToString:RCTTVRemoteEventMenu]) {
+ [subview addGestureRecognizer:self.tvRemoteHandler.tvRemoteGestureRecognizers[key]];
+ }
+ }
if (_onRequestClose) {
[subview addGestureRecognizer:_menuButtonGestureRecognizer];
}
@@ -139,6 +146,9 @@ - (void)removeReactSubview:(UIView *)subview
if (_menuButtonGestureRecognizer) {
[subview removeGestureRecognizer:_menuButtonGestureRecognizer];
}
+ for (UIGestureRecognizer *gr in self.tvRemoteHandler.tvRemoteGestureRecognizers) {
+ [subview removeGestureRecognizer:gr];
+ }
#endif
_reactSubview = nil;
}
diff --git a/local-cli/templates/HelloWorld/ios/HelloWorld.xcodeproj/project.pbxproj b/local-cli/templates/HelloWorld/ios/HelloWorld.xcodeproj/project.pbxproj
index 606ef9c915635c..a7c51152b93bbf 100644
--- a/local-cli/templates/HelloWorld/ios/HelloWorld.xcodeproj/project.pbxproj
+++ b/local-cli/templates/HelloWorld/ios/HelloWorld.xcodeproj/project.pbxproj
@@ -25,14 +25,14 @@
2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
- 2D02E4C21E0B4AEC006451C7 /* libRCTAnimation-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation-tvOS.a */; };
+ 2D02E4C21E0B4AEC006451C7 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */; };
2D02E4C31E0B4AEC006451C7 /* libRCTImage-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */; };
2D02E4C41E0B4AEC006451C7 /* libRCTLinking-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */; };
2D02E4C51E0B4AEC006451C7 /* libRCTNetwork-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */; };
2D02E4C61E0B4AEC006451C7 /* libRCTSettings-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E901DF850E9000B6D8A /* libRCTSettings-tvOS.a */; };
2D02E4C71E0B4AEC006451C7 /* libRCTText-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E941DF850E9000B6D8A /* libRCTText-tvOS.a */; };
2D02E4C81E0B4AEC006451C7 /* libRCTWebSocket-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */; };
- 2D02E4C91E0B4AEC006451C7 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3EA31DF850E9000B6D8A /* libReact.a */; };
+ 2D16E6881FA4F8E400B85C8A /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D16E6891FA4F8E400B85C8A /* libReact.a */; };
2DCD954D1E0B4F2C00145EB5 /* HelloWorldTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* HelloWorldTests.m */; };
5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */; };
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
@@ -110,6 +110,27 @@
remoteGlobalIDString = 2D02E47A1E0B4A5D006451C7;
remoteInfo = "HelloWorld-tvOS";
};
+ 2D16E6711FA4F8DC00B85C8A /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = ADD01A681E09402E00F6D226;
+ remoteInfo = "RCTBlob-tvOS";
+ };
+ 2D16E6831FA4F8DC00B85C8A /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = 3DBE0D001F3B181A0099AA32;
+ remoteInfo = fishhook;
+ };
+ 2D16E6851FA4F8DC00B85C8A /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = 3DBE0D0D1F3B181C0099AA32;
+ remoteInfo = "fishhook-tvOS";
+ };
3DAD3E831DF850E9000B6D8A /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
@@ -260,6 +281,7 @@
146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = ""; };
2D02E47B1E0B4A5D006451C7 /* HelloWorld-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "HelloWorld-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
2D02E4901E0B4A5D006451C7 /* HelloWorld-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "HelloWorld-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 2D16E6891FA4F8E400B85C8A /* libReact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libReact.a; sourceTree = BUILT_PRODUCTS_DIR; };
5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimation.xcodeproj; path = "../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj"; sourceTree = ""; };
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = ""; };
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = ""; };
@@ -299,8 +321,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 2D02E4C91E0B4AEC006451C7 /* libReact.a in Frameworks */,
- 2D02E4C21E0B4AEC006451C7 /* libRCTAnimation-tvOS.a in Frameworks */,
+ 2D16E6881FA4F8E400B85C8A /* libReact.a in Frameworks */,
+ 2D02E4C21E0B4AEC006451C7 /* libRCTAnimation.a in Frameworks */,
2D02E4C31E0B4AEC006451C7 /* libRCTImage-tvOS.a in Frameworks */,
2D02E4C41E0B4AEC006451C7 /* libRCTLinking-tvOS.a in Frameworks */,
2D02E4C51E0B4AEC006451C7 /* libRCTNetwork-tvOS.a in Frameworks */,
@@ -393,6 +415,8 @@
children = (
139FDEF41B06529B00C62182 /* libRCTWebSocket.a */,
3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */,
+ 2D16E6841FA4F8DC00B85C8A /* libfishhook.a */,
+ 2D16E6861FA4F8DC00B85C8A /* libfishhook-tvOS.a */,
);
name = Products;
sourceTree = "";
@@ -415,7 +439,6 @@
isa = PBXGroup;
children = (
146834041AC3E56700842450 /* libReact.a */,
- 3DAD3EA31DF850E9000B6D8A /* libReact.a */,
3DAD3EA51DF850E9000B6D8A /* libyoga.a */,
3DAD3EA71DF850E9000B6D8A /* libyoga.a */,
3DAD3EA91DF850E9000B6D8A /* libcxxreact.a */,
@@ -427,11 +450,19 @@
name = Products;
sourceTree = "";
};
+ 2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 2D16E6891FA4F8E400B85C8A /* libReact.a */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
5E91572E1DD0AC6500FF2AA8 /* Products */ = {
isa = PBXGroup;
children = (
5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */,
- 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation-tvOS.a */,
+ 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */,
);
name = Products;
sourceTree = "";
@@ -480,6 +511,7 @@
832341AE1AAA6A7D00B99B32 /* Libraries */,
00E356EF1AD99517003FC87E /* HelloWorldTests */,
83CBBA001A601CBA00E9B192 /* Products */,
+ 2D16E6871FA4F8E400B85C8A /* Frameworks */,
);
indentWidth = 2;
sourceTree = "";
@@ -501,6 +533,7 @@
isa = PBXGroup;
children = (
ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */,
+ 2D16E6721FA4F8DC00B85C8A /* libRCTBlob-tvOS.a */,
);
name = Products;
sourceTree = "";
@@ -732,6 +765,27 @@
remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
+ 2D16E6721FA4F8DC00B85C8A /* libRCTBlob-tvOS.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = "libRCTBlob-tvOS.a";
+ remoteRef = 2D16E6711FA4F8DC00B85C8A /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ 2D16E6841FA4F8DC00B85C8A /* libfishhook.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = libfishhook.a;
+ remoteRef = 2D16E6831FA4F8DC00B85C8A /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ 2D16E6861FA4F8DC00B85C8A /* libfishhook-tvOS.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = "libfishhook-tvOS.a";
+ remoteRef = 2D16E6851FA4F8DC00B85C8A /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
@@ -830,10 +884,10 @@
remoteRef = 5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
- 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation-tvOS.a */ = {
+ 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
- path = "libRCTAnimation-tvOS.a";
+ path = libRCTAnimation.a;
remoteRef = 5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
From a329e968fc3c67732e23ec6ff93a9bfe4530f61c Mon Sep 17 00:00:00 2001
From: Yujie Liu
Date: Thu, 9 Nov 2017 18:48:11 -0800
Subject: [PATCH 17/50] resolve iOS assets from embedded bundle path for iOS
platform
Reviewed By: zahanm
Differential Revision: D6193907
fbshipit-source-id: 09c76a5c3d6a7777a9a823c21bfcc0fe344bc83e
---
Libraries/Image/AssetSourceResolver.js | 22 +++++++++++++-
Libraries/Image/resolveAssetSource.js | 41 +++++++++++++++++---------
2 files changed, 48 insertions(+), 15 deletions(-)
diff --git a/Libraries/Image/AssetSourceResolver.js b/Libraries/Image/AssetSourceResolver.js
index 2183d1a98904d2..a240b5af71601e 100644
--- a/Libraries/Image/AssetSourceResolver.js
+++ b/Libraries/Image/AssetSourceResolver.js
@@ -52,12 +52,19 @@ class AssetSourceResolver {
serverUrl: ?string;
// where the jsbundle is being run from
jsbundleUrl: ?string;
+ // where the embedded bundle in the app is stored
+ embeddedBundleUrl: ?string;
// the asset to resolve
asset: PackagerAsset;
- constructor(serverUrl: ?string, jsbundleUrl: ?string, asset: PackagerAsset) {
+ constructor(serverUrl: ?string,
+ jsbundleUrl: ?string,
+ embeddedBundleUrl: ?string,
+ asset: PackagerAsset
+ ) {
this.serverUrl = serverUrl;
this.jsbundleUrl = jsbundleUrl;
+ this.embeddedBundleUrl = embeddedBundleUrl;
this.asset = asset;
}
@@ -69,6 +76,10 @@ class AssetSourceResolver {
return !!this.jsbundleUrl;
}
+ canLoadFromEmbeddedBundledLocation(): boolean {
+ return !!this.embeddedBundleUrl;
+ }
+
defaultAsset(): ResolvedAssetSource {
if (this.isLoadedFromServer()) {
return this.assetServerURL();
@@ -112,6 +123,15 @@ class AssetSourceResolver {
return this.fromSource(path + getScaledAssetPath(this.asset));
}
+ /**
+ * Resolves to the asset that was bundled with the app, with a scaled asset filename
+ * E.g. 'file:///sdcard/bundle/assets/AwesomeModule/icon@2x.png'
+ */
+ scaledAssetURLInEmbeddedBundleUrl(): ResolvedAssetSource {
+ const path = this.embeddedBundleUrl || 'file://';
+ return this.fromSource(path + getScaledAssetPath(this.asset));
+ }
+
/**
* The default location of assets bundled with the app, located by
* resource identifier
diff --git a/Libraries/Image/resolveAssetSource.js b/Libraries/Image/resolveAssetSource.js
index 18350ce2c53493..aba63045e4d18b 100644
--- a/Libraries/Image/resolveAssetSource.js
+++ b/Libraries/Image/resolveAssetSource.js
@@ -19,7 +19,7 @@ const NativeModules = require('NativeModules');
import type { ResolvedAssetSource } from 'AssetSourceResolver';
-let _customSourceTransformer, _serverURL, _scriptURL;
+let _customSourceTransformer, _serverURL, _scriptURL, _embeddedBundleURL;
function getDevServerURL(): ?string {
if (_serverURL === undefined) {
@@ -36,30 +36,38 @@ function getDevServerURL(): ?string {
return _serverURL;
}
-function getScriptURL(): ?string {
- if (_scriptURL === undefined) {
- const scriptURL = NativeModules.SourceCode.scriptURL;
- if (!scriptURL) {
- // scriptURL is falsy, we have nothing to go on here
- _scriptURL = null;
- return _scriptURL;
- }
+function _coerceLocalScriptURL(scriptURL: ?string): ?string {
+ if (scriptURL) {
if (scriptURL.startsWith('assets://')) {
// android: running from within assets, no offline path to use
- _scriptURL = null;
- return _scriptURL;
+ return null;
}
- _scriptURL = scriptURL.substring(0, scriptURL.lastIndexOf('/') + 1);
+ scriptURL = scriptURL.substring(0, scriptURL.lastIndexOf('/') + 1);
if (!scriptURL.startsWith('file://')) {
// Add file protocol in case we have an absolute file path and not a URL.
// This shouldn't really be necessary. scriptURL should be a URL.
- _scriptURL = 'file://' + _scriptURL;
+ scriptURL = 'file://' + scriptURL;
}
}
+ return scriptURL;
+}
+function getScriptURL(): ?string {
+ if (_scriptURL === undefined) {
+ const scriptURL = NativeModules.SourceCode.scriptURL;
+ _scriptURL = _coerceLocalScriptURL(scriptURL);
+ }
return _scriptURL;
}
+function getEmbeddedBundledURL(): ?string {
+ if (_embeddedBundleURL === undefined) {
+ const scriptURL = NativeModules.SourceCode.embeddedBundleURL;
+ _embeddedBundleURL = _coerceLocalScriptURL(scriptURL);
+ }
+ return _embeddedBundleURL;
+}
+
function setCustomSourceTransformer(
transformer: (resolver: AssetSourceResolver) => ResolvedAssetSource,
): void {
@@ -80,7 +88,12 @@ function resolveAssetSource(source: any): ?ResolvedAssetSource {
return null;
}
- const resolver = new AssetSourceResolver(getDevServerURL(), getScriptURL(), asset);
+ const resolver = new AssetSourceResolver(
+ getDevServerURL(),
+ getScriptURL(),
+ getEmbeddedBundledURL(),
+ asset,
+ );
if (_customSourceTransformer) {
return _customSourceTransformer(resolver);
}
From 58c3bc490143b8d7831a00289e2565f49f5389ef Mon Sep 17 00:00:00 2001
From: Brian Solon
Date: Thu, 9 Nov 2017 22:18:02 -0800
Subject: [PATCH 18/50] Fix typo in Image.android.js & Image.ios.js
Summary:
Fixing a typo.
N/A
[IOS] [MINOR] [Image] - Fixed a typo in an error message
[ANDROID] [MINOR] [Image] - Fixed a typo in an error message
Closes https://github.com/facebook/react-native/pull/16777
Differential Revision: D6295564
Pulled By: shergin
fbshipit-source-id: eb6274701b6406f26b9eda1c35632cb2ce0392d7
---
Libraries/Image/Image.android.js | 2 +-
Libraries/Image/Image.ios.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Libraries/Image/Image.android.js b/Libraries/Image/Image.android.js
index b953d085515074..d0169794642f61 100644
--- a/Libraries/Image/Image.android.js
+++ b/Libraries/Image/Image.android.js
@@ -274,7 +274,7 @@ var Image = createReactClass({
}
if (this.props.children) {
- throw new Error('The component cannot contain children. If you want to render content on top of the image, consider using aboslute positioning.');
+ throw new Error('The component cannot contain children. If you want to render content on top of the image, consider using absolute positioning.');
}
if (source && (source.uri || Array.isArray(source))) {
diff --git a/Libraries/Image/Image.ios.js b/Libraries/Image/Image.ios.js
index 6a5f826027e1d7..cc7aeec42430c7 100644
--- a/Libraries/Image/Image.ios.js
+++ b/Libraries/Image/Image.ios.js
@@ -374,7 +374,7 @@ const Image = createReactClass({
}
if (this.props.children) {
- throw new Error('The component cannot contain children. If you want to render content on top of the image, consider using aboslute positioning.');
+ throw new Error('The component cannot contain children. If you want to render content on top of the image, consider using absolute positioning.');
}
return (
From 7fb3a9229df52bd45076470d059f245a8147cd2a Mon Sep 17 00:00:00 2001
From: Tim Wang
Date: Fri, 10 Nov 2017 09:56:38 -0800
Subject: [PATCH 19/50] Fix Jest mocks for NetInfo module.
Summary:
Jest mock for `NetInfo.getConnectionInfo()` is missing. Tests are fail with error message:
```
TypeError: _reactNative.NetInfo.getConnectionInfo is not a function
```
And cleaned code in this files for unified code styles.
Run test with usage of `NetInfo.getConnectionInfo()`
[GENERAL] [BUGFIX] [jest/setup.js] - Fix Jest mocks for NetInfo module
Closes https://github.com/facebook/react-native/pull/16722
Differential Revision: D6298133
Pulled By: hramos
fbshipit-source-id: 589cf6fed93965e7a09823015f2793f5c68a9c3b
---
jest/setup.js | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/jest/setup.js b/jest/setup.js
index 9a04acb2316421..2f55f2bd2fc068 100644
--- a/jest/setup.js
+++ b/jest/setup.js
@@ -162,7 +162,7 @@ const mockNativeModules = {
},
ImageLoader: {
getSize: jest.fn(
- (url) => new Promise(() => ({width: 320, height: 240}))
+ (url) => Promise.resolve({width: 320, height: 240})
),
prefetchImage: jest.fn(),
},
@@ -179,11 +179,11 @@ const mockNativeModules = {
Linking: {
openURL: jest.fn(),
canOpenURL: jest.fn(
- () => new Promise((resolve) => resolve(true))
+ () => Promise.resolve(true)
),
addEventListener: jest.fn(),
getInitialURL: jest.fn(
- () => new Promise((resolve) => resolve())
+ () => Promise.resolve()
),
removeEventListener: jest.fn(),
},
@@ -195,15 +195,23 @@ const mockNativeModules = {
ModalFullscreenViewManager: {},
NetInfo: {
fetch: jest.fn(
- () => new Promise((resolve) => resolve())
+ () => Promise.resolve()
+ ),
+ getConnectionInfo: jest.fn(
+ () => Promise.resolve()
),
addEventListener: jest.fn(),
+ removeEventListener: jest.fn(),
isConnected: {
fetch: jest.fn(
- () => new Promise((resolve) => resolve())
+ () => Promise.resolve()
),
addEventListener: jest.fn(),
+ removeEventListener: jest.fn(),
},
+ isConnectionExpensive: jest.fn(
+ () => Promise.resolve()
+ ),
},
Networking: {
sendRequest: jest.fn(),
From eb0d6470e54663538610a70ab0bae9847eb33673 Mon Sep 17 00:00:00 2001
From: Caleb Meredith
Date: Fri, 10 Nov 2017 21:03:52 -0800
Subject: [PATCH 20/50] Flow 0.59 xplat/js deploy
Reviewed By: avikchaudhuri
Differential Revision: D6300238
fbshipit-source-id: a6839fa2a9bbc50c3832a3f5b1cac2a6d2bd96b7
---
.flowconfig | 6 +--
Libraries/Animated/src/Easing.js | 41 +++++++++++++++++++
Libraries/CameraRoll/CameraRoll.js | 4 ++
Libraries/Experimental/WindowedListView.js | 5 +++
.../Lists/ListView/__mocks__/ListViewMock.js | 5 +++
Libraries/Share/Share.js | 4 +-
Libraries/StyleSheet/StyleSheetValidation.js | 8 ++++
local-cli/templates/HelloWorld/_flowconfig | 6 +--
package.json | 2 +-
9 files changed, 72 insertions(+), 9 deletions(-)
diff --git a/.flowconfig b/.flowconfig
index 7b6a007cfe3422..fc9fe6762baa0f 100644
--- a/.flowconfig
+++ b/.flowconfig
@@ -46,12 +46,12 @@ suppress_type=$FlowFixMeProps
suppress_type=$FlowFixMeState
suppress_type=$FixMe
-suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(5[0-8]\\|[1-4][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*[react_native_oss|react_native_fb][a-z,_]*\\)?)\\)
-suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(5[0-8]\\|[1-4][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*[react_native_oss|react_native_fb][a-z,_]*\\)?)\\)?:? #[0-9]+
+suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(5[0-9]\\|[1-4][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*[react_native_oss|react_native_fb][a-z,_]*\\)?)\\)
+suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(5[0-9]\\|[1-4][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*[react_native_oss|react_native_fb][a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
unsafe.enable_getters_and_setters=true
[version]
-^0.58.0
+^0.59.0
diff --git a/Libraries/Animated/src/Easing.js b/Libraries/Animated/src/Easing.js
index 7b396ea4c0564c..ddd86557c5d637 100644
--- a/Libraries/Animated/src/Easing.js
+++ b/Libraries/Animated/src/Easing.js
@@ -62,6 +62,10 @@ class Easing {
/**
* A stepping function, returns 1 for any positive value of `n`.
*/
+ /* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an error
+ * caught by Flow 0.59 which was not caught before. Most likely, this error
+ * is because an exported function parameter is missing an annotation.
+ * Without an annotation, these parameters are uncovered by Flow. */
static step0(n) {
return n > 0 ? 1 : 0;
}
@@ -69,6 +73,10 @@ class Easing {
/**
* A stepping function, returns 1 if `n` is greater than or equal to 1.
*/
+ /* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an error
+ * caught by Flow 0.59 which was not caught before. Most likely, this error
+ * is because an exported function parameter is missing an annotation.
+ * Without an annotation, these parameters are uncovered by Flow. */
static step1(n) {
return n >= 1 ? 1 : 0;
}
@@ -79,6 +87,10 @@ class Easing {
*
* http://cubic-bezier.com/#0,0,1,1
*/
+ /* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an error
+ * caught by Flow 0.59 which was not caught before. Most likely, this error
+ * is because an exported function parameter is missing an annotation.
+ * Without an annotation, these parameters are uncovered by Flow. */
static linear(t) {
return t;
}
@@ -102,6 +114,10 @@ class Easing {
*
* http://easings.net/#easeInQuad
*/
+ /* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an error
+ * caught by Flow 0.59 which was not caught before. Most likely, this error
+ * is because an exported function parameter is missing an annotation.
+ * Without an annotation, these parameters are uncovered by Flow. */
static quad(t) {
return t * t;
}
@@ -112,6 +128,10 @@ class Easing {
*
* http://easings.net/#easeInCubic
*/
+ /* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an error
+ * caught by Flow 0.59 which was not caught before. Most likely, this error
+ * is because an exported function parameter is missing an annotation.
+ * Without an annotation, these parameters are uncovered by Flow. */
static cubic(t) {
return t * t * t;
}
@@ -122,7 +142,16 @@ class Easing {
* n = 4: http://easings.net/#easeInQuart
* n = 5: http://easings.net/#easeInQuint
*/
+ /* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an error
+ * caught by Flow 0.59 which was not caught before. Most likely, this error
+ * is because an exported function parameter is missing an annotation.
+ * Without an annotation, these parameters are uncovered by Flow. */
static poly(n) {
+ /* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an
+ * error caught by Flow 0.59 which was not caught before. Most likely, this
+ * error is because an exported function parameter is missing an
+ * annotation. Without an annotation, these parameters are uncovered by
+ * Flow. */
return (t) => Math.pow(t, n);
}
@@ -131,6 +160,10 @@ class Easing {
*
* http://easings.net/#easeInSine
*/
+ /* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an error
+ * caught by Flow 0.59 which was not caught before. Most likely, this error
+ * is because an exported function parameter is missing an annotation.
+ * Without an annotation, these parameters are uncovered by Flow. */
static sin(t) {
return 1 - Math.cos(t * Math.PI / 2);
}
@@ -140,6 +173,10 @@ class Easing {
*
* http://easings.net/#easeInCirc
*/
+ /* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an error
+ * caught by Flow 0.59 which was not caught before. Most likely, this error
+ * is because an exported function parameter is missing an annotation.
+ * Without an annotation, these parameters are uncovered by Flow. */
static circle(t) {
return 1 - Math.sqrt(1 - t * t);
}
@@ -149,6 +186,10 @@ class Easing {
*
* http://easings.net/#easeInExpo
*/
+ /* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an error
+ * caught by Flow 0.59 which was not caught before. Most likely, this error
+ * is because an exported function parameter is missing an annotation.
+ * Without an annotation, these parameters are uncovered by Flow. */
static exp(t) {
return Math.pow(2, 10 * (t - 1));
}
diff --git a/Libraries/CameraRoll/CameraRoll.js b/Libraries/CameraRoll/CameraRoll.js
index 66d8bd3eb2bf81..b9da61a56db4b8 100644
--- a/Libraries/CameraRoll/CameraRoll.js
+++ b/Libraries/CameraRoll/CameraRoll.js
@@ -255,6 +255,10 @@ class CameraRoll {
* }
* ```
*/
+ /* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an error
+ * caught by Flow 0.59 which was not caught before. Most likely, this error
+ * is because an exported function parameter is missing an annotation.
+ * Without an annotation, these parameters are uncovered by Flow. */
static getPhotos(params) {
if (__DEV__) {
checkPropTypes(
diff --git a/Libraries/Experimental/WindowedListView.js b/Libraries/Experimental/WindowedListView.js
index 05e16ee7bf63c6..afbff25a42ba75 100644
--- a/Libraries/Experimental/WindowedListView.js
+++ b/Libraries/Experimental/WindowedListView.js
@@ -176,6 +176,11 @@ class WindowedListView extends React.Component {
maxNumToRender: 30,
numToRenderAhead: 10,
viewablePercentThreshold: 50,
+ /* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an
+ * error caught by Flow 0.59 which was not caught before. Most likely, this
+ * error is because an exported function parameter is missing an
+ * annotation. Without an annotation, these parameters are uncovered by
+ * Flow. */
renderScrollComponent: (props) => ,
disableIncrementalRendering: false,
recomputeRowsBatchingPeriod: 10, // This should capture most events that happen within a frame
diff --git a/Libraries/Lists/ListView/__mocks__/ListViewMock.js b/Libraries/Lists/ListView/__mocks__/ListViewMock.js
index 2c27303d7e7294..732dc5e1caf208 100644
--- a/Libraries/Lists/ListView/__mocks__/ListViewMock.js
+++ b/Libraries/Lists/ListView/__mocks__/ListViewMock.js
@@ -19,6 +19,11 @@ const StaticRenderer = require('StaticRenderer');
class ListViewMock extends React.Component<$FlowFixMeProps> {
static latestRef: ?ListViewMock;
static defaultProps = {
+ /* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an
+ * error caught by Flow 0.59 which was not caught before. Most likely, this
+ * error is because an exported function parameter is missing an
+ * annotation. Without an annotation, these parameters are uncovered by
+ * Flow. */
renderScrollComponent: props => ,
};
componentDidMount() {
diff --git a/Libraries/Share/Share.js b/Libraries/Share/Share.js
index 457cf4a9610353..44d7433218bed2 100644
--- a/Libraries/Share/Share.js
+++ b/Libraries/Share/Share.js
@@ -111,13 +111,13 @@ class Share {
/**
* The content was successfully shared.
*/
- static get sharedAction() { return 'sharedAction'; }
+ static get sharedAction(): string { return 'sharedAction'; }
/**
* The dialog has been dismissed.
* @platform ios
*/
- static get dismissedAction() { return 'dismissedAction'; }
+ static get dismissedAction(): string { return 'dismissedAction'; }
}
diff --git a/Libraries/StyleSheet/StyleSheetValidation.js b/Libraries/StyleSheet/StyleSheetValidation.js
index c2ee260c89a44b..dadf735dde20e4 100644
--- a/Libraries/StyleSheet/StyleSheetValidation.js
+++ b/Libraries/StyleSheet/StyleSheetValidation.js
@@ -24,6 +24,10 @@ var invariant = require('fbjs/lib/invariant');
const ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
class StyleSheetValidation {
+ /* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an error
+ * caught by Flow 0.59 which was not caught before. Most likely, this error
+ * is because an exported function parameter is missing an annotation.
+ * Without an annotation, these parameters are uncovered by Flow. */
static validateStyleProp(prop, style, caller) {
if (!__DEV__) {
return;
@@ -59,6 +63,10 @@ class StyleSheetValidation {
}
}
+ /* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an error
+ * caught by Flow 0.59 which was not caught before. Most likely, this error
+ * is because an exported function parameter is missing an annotation.
+ * Without an annotation, these parameters are uncovered by Flow. */
static validateStyle(name, styles) {
if (!__DEV__) {
return;
diff --git a/local-cli/templates/HelloWorld/_flowconfig b/local-cli/templates/HelloWorld/_flowconfig
index d834b93707e493..9a069e497282f3 100644
--- a/local-cli/templates/HelloWorld/_flowconfig
+++ b/local-cli/templates/HelloWorld/_flowconfig
@@ -37,12 +37,12 @@ suppress_type=$FlowFixMeProps
suppress_type=$FlowFixMeState
suppress_type=$FixMe
-suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(5[0-8]\\|[1-4][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
-suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(5[0-8]\\|[1-4][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
+suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(5[0-9]\\|[1-4][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
+suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(5[0-9]\\|[1-4][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
unsafe.enable_getters_and_setters=true
[version]
-^0.58.0
+^0.59.0
diff --git a/package.json b/package.json
index 364ce0fa0c1dd4..22e3f8ad30e9cd 100644
--- a/package.json
+++ b/package.json
@@ -208,7 +208,7 @@
"eslint-plugin-flowtype": "^2.33.0",
"eslint-plugin-prettier": "2.1.1",
"eslint-plugin-react": "^7.2.1",
- "flow-bin": "^0.58.0",
+ "flow-bin": "^0.59.0",
"jest": "21.3.0-beta.8",
"prettier": "1.7.0",
"react": "16.0.0",
From 6d92046c56794a6a62bc07598545a23a7b53cdc0 Mon Sep 17 00:00:00 2001
From: Rafael Oleza
Date: Sat, 11 Nov 2017 07:03:08 -0800
Subject: [PATCH 21/50] Fix dependencies script when its running with dev=false
Reviewed By: alp
Differential Revision: D6307190
fbshipit-source-id: 21f339ff9c24d58df2630cd6b957e7539880f001
---
local-cli/dependencies/dependencies.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/local-cli/dependencies/dependencies.js b/local-cli/dependencies/dependencies.js
index f491e7f011f095..fc6b22c7b96cc6 100644
--- a/local-cli/dependencies/dependencies.js
+++ b/local-cli/dependencies/dependencies.js
@@ -34,6 +34,7 @@ function dependencies(argv, config, args, packagerInstance) {
getPolyfills: config.getPolyfills,
getTransformOptions: config.getTransformOptions,
hasteImpl: config.hasteImpl,
+ postMinifyProcess: config.postMinifyProcess,
transformModulePath: transformModulePath,
extraNodeModules: config.extraNodeModules,
verbose: config.verbose,
From e75bd87a76726a9b075061ef76156705b3c1e872 Mon Sep 17 00:00:00 2001
From: Valentin Shergin
Date: Sat, 11 Nov 2017 21:15:17 -0800
Subject: [PATCH 22/50] Introducing RCTSurfaceHostingComponent
Summary: RCTSurfaceHostingComponent is ComponentKit component represents given Surface instance.
Differential Revision: D6217104
fbshipit-source-id: 50805d97e744de24a188bc97b33de4709e785aae
---
.../RCTSurfaceHostingComponent+Internal.h | 22 +++
.../RCTSurfaceHostingComponent.h | 22 +++
.../RCTSurfaceHostingComponent.mm | 104 +++++++++++++
.../RCTSurfaceHostingComponentController.h | 14 ++
.../RCTSurfaceHostingComponentController.mm | 143 ++++++++++++++++++
.../RCTSurfaceHostingComponentOptions.h | 22 +++
.../RCTSurfaceHostingComponentState.h | 22 +++
.../RCTSurfaceHostingComponentState.mm | 43 ++++++
8 files changed, 392 insertions(+)
create mode 100644 Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponent+Internal.h
create mode 100644 Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponent.h
create mode 100644 Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponent.mm
create mode 100644 Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponentController.h
create mode 100644 Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponentController.mm
create mode 100644 Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponentOptions.h
create mode 100644 Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponentState.h
create mode 100644 Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponentState.mm
diff --git a/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponent+Internal.h b/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponent+Internal.h
new file mode 100644
index 00000000000000..184ff32a9342c6
--- /dev/null
+++ b/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponent+Internal.h
@@ -0,0 +1,22 @@
+/**
+ * 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
+#import
+
+@class RCTSurface;
+@class RCTSurfaceHostingComponentState;
+
+@interface RCTSurfaceHostingComponent ()
+
+@property (nonatomic, strong, readonly) RCTSurface *surface;
+@property (nonatomic, retain, readonly) RCTSurfaceHostingComponentState *state;
+@property (nonatomic, assign, readonly) RCTSurfaceHostingComponentOptions options;
+
+@end
diff --git a/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponent.h b/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponent.h
new file mode 100644
index 00000000000000..c1dd823afb5bb7
--- /dev/null
+++ b/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponent.h
@@ -0,0 +1,22 @@
+/**
+ * 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
+#import
+
+@class RCTSurface;
+
+/**
+ * ComponentKit component represents given Surface instance.
+ */
+@interface RCTSurfaceHostingComponent : CKComponent
+
++ (instancetype)newWithSurface:(RCTSurface *)surface options:(RCTSurfaceHostingComponentOptions)options;
+
+@end
diff --git a/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponent.mm b/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponent.mm
new file mode 100644
index 00000000000000..010bd961c40530
--- /dev/null
+++ b/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponent.mm
@@ -0,0 +1,104 @@
+/**
+ * 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 "RCTSurfaceHostingComponent.h"
+#import "RCTSurfaceHostingComponent+Internal.h"
+
+#import
+
+#import
+#import
+#import
+
+#import "RCTSurfaceHostingComponentState.h"
+
+@implementation RCTSurfaceHostingComponent
+
++ (id)initialState
+{
+ return [RCTSurfaceHostingComponentState new];
+}
+
++ (instancetype)newWithSurface:(RCTSurface *)surface options:(RCTSurfaceHostingComponentOptions)options
+{
+ CKComponentScope scope(self, surface);
+
+ RCTSurfaceHostingComponentState *const state = scope.state();
+
+ RCTSurfaceHostingComponentState *const newState =
+ [RCTSurfaceHostingComponentState newWithStage:surface.stage
+ intrinsicSize:surface.intrinsicSize];
+
+ if (![state isEqual:newState]) {
+ CKComponentScope::replaceState(scope, newState);
+ }
+
+ RCTSurfaceHostingComponent *const component =
+ [super newWithView:{[UIView class]} size:{}];
+
+ if (component) {
+ component->_state = scope.state();
+ component->_surface = surface;
+ component->_options = options;
+ }
+
+ return component;
+}
+
+- (CKComponentLayout)computeLayoutThatFits:(CKSizeRange)constrainedSize
+{
+ // Optimistically communicating layout constraints to the `_surface`,
+ // just to provide layout constraints to React Native as early as possible.
+ // React Native *may* use this info later during applying the own state and
+ // related laying out in parallel with ComponentKit execution.
+ // This call will not interfere (or introduce any negative side effects) with
+ // following invocation of `sizeThatFitsMinimumSize:maximumSize:`.
+ // A weak point: We assume here that this particular layout will be
+ // mounted eventually, which is technically not guaranteed by ComponentKit.
+ // Therefore we also assume that the last layout calculated in a sequence
+ // will be mounted anyways, which is probably true for all *real* use cases.
+ // We plan to tackle this problem during the next big step in improving
+ // interop compatibilities of React Native which will enable us granularly
+ // control React Native mounting blocks and, as a result, implement
+ // truly synchronous mounting stage between React Native and ComponentKit.
+ [_surface setMinimumSize:constrainedSize.min
+ maximumSize:constrainedSize.max];
+
+ // Just in case of the very first building pass, we give React Native a chance
+ // to prepare its internals for coming synchronous measuring.
+ [_surface synchronouslyWaitForStage:RCTSurfaceStageSurfaceDidInitialLayout
+ timeout:_options.synchronousLayoutingTimeout];
+
+ CGSize fittingSize = CGSizeZero;
+ if (_surface.stage & RCTSurfaceStageSurfaceDidInitialLayout) {
+ fittingSize = [_surface sizeThatFitsMinimumSize:constrainedSize.min
+ maximumSize:constrainedSize.max];
+ }
+ else {
+ fittingSize = _options.activityIndicatorSize;
+ }
+
+ fittingSize = constrainedSize.clamp(fittingSize);
+ return {self, fittingSize};
+}
+
+- (CKComponentBoundsAnimation)boundsAnimationFromPreviousComponent:(RCTSurfaceHostingComponent *)previousComponent
+{
+ if (_options.boundsAnimations && (previousComponent->_state.stage != _state.stage)) {
+ return {
+ .mode = CKComponentBoundsAnimationModeDefault,
+ .duration = 0.25,
+ .options = UIViewAnimationOptionCurveEaseInOut,
+ };
+ }
+
+ return {};
+}
+
+@end
diff --git a/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponentController.h b/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponentController.h
new file mode 100644
index 00000000000000..04b8fcafa308c8
--- /dev/null
+++ b/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponentController.h
@@ -0,0 +1,14 @@
+/**
+ * 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
+
+@interface RCTSurfaceHostingComponentController : CKComponentController
+
+@end
diff --git a/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponentController.mm b/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponentController.mm
new file mode 100644
index 00000000000000..c44dbcd007e162
--- /dev/null
+++ b/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponentController.mm
@@ -0,0 +1,143 @@
+/**
+ * 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 "RCTSurfaceHostingComponentController.h"
+
+#import
+#import
+#import
+#import
+#import
+
+#import "RCTSurfaceHostingComponent+Internal.h"
+#import "RCTSurfaceHostingComponent.h"
+#import "RCTSurfaceHostingComponentState.h"
+
+@interface RCTSurfaceHostingComponentController()
+@end
+
+@implementation RCTSurfaceHostingComponentController {
+ RCTSurface *_surface;
+}
+
+- (instancetype)initWithComponent:(RCTSurfaceHostingComponent *)component
+{
+ if (self = [super initWithComponent:component]) {
+ [self updateSurfaceWithComponent:component];
+ }
+
+ return self;
+}
+
+#pragma mark - Lifecycle
+
+- (void)didMount
+{
+ [super didMount];
+ [self mountSurfaceView];
+}
+
+- (void)didRemount
+{
+ [super didRemount];
+ [self mountSurfaceView];
+}
+
+- (void)didUpdateComponent
+{
+ [super didUpdateComponent];
+ [self updateSurfaceWithComponent:(RCTSurfaceHostingComponent *)self.component];
+}
+
+- (void)didUnmount
+{
+ [super didUnmount];
+ [self unmountSurfaceView];
+}
+
+#pragma mark - Helpers
+
+- (void)updateSurfaceWithComponent:(RCTSurfaceHostingComponent *)component
+{
+ // Updating `surface`
+ RCTSurface *const surface = component.surface;
+ if (surface != _surface) {
+ if (_surface.delegate == self) {
+ _surface.delegate = nil;
+ }
+
+ _surface = surface;
+ _surface.delegate = self;
+ }
+}
+
+- (void)setIntrinsicSize:(CGSize)intrinsicSize
+{
+ [self.component updateState:^(RCTSurfaceHostingComponentState *state) {
+ return [RCTSurfaceHostingComponentState newWithStage:state.stage
+ intrinsicSize:intrinsicSize];
+ } mode:[self suitableStateUpdateMode]];
+}
+
+- (void)setStage:(RCTSurfaceStage)stage
+{
+ [self.component updateState:^(RCTSurfaceHostingComponentState *state) {
+ return [RCTSurfaceHostingComponentState newWithStage:stage
+ intrinsicSize:state.intrinsicSize];
+ } mode:[self suitableStateUpdateMode]];
+}
+
+- (CKUpdateMode)suitableStateUpdateMode
+{
+ return ((RCTSurfaceHostingComponent *)self.component).options.synchronousStateUpdates && RCTIsMainQueue() ? CKUpdateModeSynchronous : CKUpdateModeAsynchronous;
+}
+
+- (void)mountSurfaceView
+{
+ UIView *const surfaceView = _surface.view;
+
+ const CKComponentViewContext &context = [[self component] viewContext];
+
+ UIView *const superview = context.view;
+ superview.clipsToBounds = YES;
+
+ RCTAssert([superview.subviews count] <= 1, @"Should never have more than a single stateful subview.");
+
+ UIView *const existingSurfaceView = [superview.subviews lastObject];
+ if (existingSurfaceView != surfaceView) {
+ [existingSurfaceView removeFromSuperview];
+ surfaceView.frame = superview.bounds;
+ surfaceView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ [superview addSubview:surfaceView];
+ }
+}
+
+- (void)unmountSurfaceView
+{
+ const CKComponentViewContext &context = [[self component] viewContext];
+
+ UIView *const superview = context.view;
+ RCTAssert([superview.subviews count] <= 1, @"Should never have more than a single stateful subview.");
+ UIView *const existingSurfaceView = [superview.subviews lastObject];
+ [existingSurfaceView removeFromSuperview];
+}
+
+#pragma mark - RCTSurfaceDelegate
+
+- (void)surface:(RCTSurface *)surface didChangeIntrinsicSize:(CGSize)intrinsicSize
+{
+ [self setIntrinsicSize:intrinsicSize];
+}
+
+- (void)surface:(RCTSurface *)surface didChangeStage:(RCTSurfaceStage)stage
+{
+ [self setStage:stage];
+}
+
+@end
diff --git a/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponentOptions.h b/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponentOptions.h
new file mode 100644
index 00000000000000..001cbd84e1f7a7
--- /dev/null
+++ b/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponentOptions.h
@@ -0,0 +1,22 @@
+/**
+ * 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
+
+#import
+
+typedef CKComponent *(^RCTSurfaceHostingComponentOptionsActivityIndicatorComponentFactory)();
+
+struct RCTSurfaceHostingComponentOptions {
+ NSTimeInterval synchronousLayoutingTimeout = 0.350;
+ BOOL synchronousStateUpdates = YES;
+ CGSize activityIndicatorSize = {44.0, 44.0};
+ BOOL boundsAnimations = YES;
+ RCTSurfaceHostingComponentOptionsActivityIndicatorComponentFactory activityIndicatorComponentFactory = nil;
+};
diff --git a/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponentState.h b/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponentState.h
new file mode 100644
index 00000000000000..b1279aaa595322
--- /dev/null
+++ b/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponentState.h
@@ -0,0 +1,22 @@
+/**
+ * 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
+
+#import
+
+@interface RCTSurfaceHostingComponentState: NSObject
+
+@property (nonatomic, readonly, assign) CGSize intrinsicSize;
+@property (nonatomic, readonly, assign) RCTSurfaceStage stage;
+
++ (instancetype)newWithStage:(RCTSurfaceStage)stage
+ intrinsicSize:(CGSize)intrinsicSize;
+
+@end
diff --git a/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponentState.mm b/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponentState.mm
new file mode 100644
index 00000000000000..f5573db67fc50f
--- /dev/null
+++ b/Libraries/SurfaceHostingComponent/RCTSurfaceHostingComponentState.mm
@@ -0,0 +1,43 @@
+/**
+ * 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 "RCTSurfaceHostingComponentState.h"
+
+@implementation RCTSurfaceHostingComponentState
+
++ (instancetype)newWithStage:(RCTSurfaceStage)stage
+ intrinsicSize:(CGSize)intrinsicSize
+{
+ return [[self alloc] initWithStage:stage intrinsicSize:intrinsicSize];
+}
+
+
+- (instancetype)initWithStage:(RCTSurfaceStage)stage
+ intrinsicSize:(CGSize)intrinsicSize
+{
+ if (self = [super init]) {
+ _stage = stage;
+ _intrinsicSize = intrinsicSize;
+ }
+
+ return self;
+}
+
+- (BOOL)isEqual:(RCTSurfaceHostingComponentState *)other
+{
+ if (other == self) {
+ return YES;
+ }
+
+ return
+ _stage == other->_stage &&
+ CGSizeEqualToSize(_intrinsicSize, other->_intrinsicSize);
+}
+
+@end
From aa83b5a0ca30736b2800833bcc6149dcbe8436fa Mon Sep 17 00:00:00 2001
From: Valentin Shergin
Date: Sat, 11 Nov 2017 21:15:20 -0800
Subject: [PATCH 23/50] Introducing RCTSurfaceBackedComponent
Summary:
RCTSurfaceBackedComponent is ComponentKit component represents a React Native Surface created
(and stored in the state) with given `bridge`, `moduleName`, and `properties`.
Differential Revision: D6217103
fbshipit-source-id: 2849f68e1975562cd47851bda232e389705b4229
---
.../RCTSurfaceBackedComponent.h | 28 ++++++++
.../RCTSurfaceBackedComponent.mm | 68 +++++++++++++++++++
.../RCTSurfaceBackedComponentState.h | 20 ++++++
.../RCTSurfaceBackedComponentState.mm | 30 ++++++++
4 files changed, 146 insertions(+)
create mode 100644 Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponent.h
create mode 100644 Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponent.mm
create mode 100644 Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponentState.h
create mode 100644 Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponentState.mm
diff --git a/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponent.h b/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponent.h
new file mode 100644
index 00000000000000..49017bda5bdc92
--- /dev/null
+++ b/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponent.h
@@ -0,0 +1,28 @@
+/**
+ * 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
+#import
+#import
+
+@class RCTBridge;
+
+/**
+ * ComponentKit component represents a React Native Surface created
+ * (and stored in the state) with given `bridge`, `moduleName`,
+ * and `properties`.
+ */
+@interface RCTSurfaceBackedComponent : CKCompositeComponent
+
++ (instancetype)newWithBridge:(RCTBridge *)bridge
+ moduleName:(NSString *)moduleName
+ properties:(NSDictionary *)properties
+ options:(RCTSurfaceHostingComponentOptions)options;
+
+@end
diff --git a/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponent.mm b/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponent.mm
new file mode 100644
index 00000000000000..74e03c5cf2ca88
--- /dev/null
+++ b/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponent.mm
@@ -0,0 +1,68 @@
+/**
+ * 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 "RCTSurfaceBackedComponent.h"
+
+#import
+
+#import
+#import
+#import
+#import
+
+#import "RCTSurfaceBackedComponentState.h"
+
+@implementation RCTSurfaceBackedComponent
+
++ (id)initialState
+{
+ return [RCTSurfaceBackedComponentState new];
+}
+
++ (instancetype)newWithBridge:(RCTBridge *)bridge
+ moduleName:(NSString *)moduleName
+ properties:(NSDictionary *)properties
+ options:(RCTSurfaceHostingComponentOptions)options
+{
+ CKComponentScope scope(self, moduleName);
+
+ RCTSurfaceBackedComponentState *state = scope.state();
+
+ if (state.surface == nil || state.surface.bridge != bridge || ![state.surface.moduleName isEqualToString:moduleName]) {
+ RCTSurface *surface =
+ [[RCTSurface alloc] initWithBridge:bridge
+ moduleName:moduleName
+ initialProperties:properties];
+
+ state = [RCTSurfaceBackedComponentState newWithSurface:surface];
+
+ CKComponentScope::replaceState(scope, state);
+ }
+ else {
+ if (![state.surface.properties isEqualToDictionary:properties]) {
+ state.surface.properties = properties;
+ }
+ }
+
+ RCTSurfaceHostingComponent *surfaceHostingComponent =
+ [RCTSurfaceHostingComponent newWithSurface:state.surface
+ options:options];
+
+ CKComponent *component;
+ if (options.activityIndicatorComponentFactory == nil || state.surface.stage & RCTSurfaceStageSurfaceDidInitialLayout) {
+ component = surfaceHostingComponent;
+ } else {
+ component = [CKOverlayLayoutComponent newWithComponent:surfaceHostingComponent
+ overlay:options.activityIndicatorComponentFactory()];
+ }
+
+ return [super newWithComponent:component];
+}
+
+@end
diff --git a/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponentState.h b/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponentState.h
new file mode 100644
index 00000000000000..819d927d0ea444
--- /dev/null
+++ b/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponentState.h
@@ -0,0 +1,20 @@
+/**
+ * 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
+
+@class RCTSurface;
+
+@interface RCTSurfaceBackedComponentState: NSObject
+
+@property (atomic, readonly, strong) RCTSurface *surface;
+
++ (instancetype)newWithSurface:(RCTSurface *)surface;
+
+@end
diff --git a/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponentState.mm b/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponentState.mm
new file mode 100644
index 00000000000000..25d1819a552aac
--- /dev/null
+++ b/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponentState.mm
@@ -0,0 +1,30 @@
+/**
+ * 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 "RCTSurfaceBackedComponentState.h"
+
+#import
+
+@implementation RCTSurfaceBackedComponentState
+
++ (instancetype)newWithSurface:(RCTSurface *)surface
+{
+ return [[self alloc] initWithSurface:surface];
+}
+
+- (instancetype)initWithSurface:(RCTSurface *)surface
+{
+ if (self == [super init]) {
+ _surface = surface;
+ }
+
+ return self;
+}
+
+@end
From d79e245d19f7f246322bc657b407198b15cb1b98 Mon Sep 17 00:00:00 2001
From: Wenjing Wang
Date: Sun, 12 Nov 2017 12:52:19 -0800
Subject: [PATCH 24/50] AMA changes to support disk cache
Reviewed By: fred2028
Differential Revision: D6295287
fbshipit-source-id: 70ae7dfba2edb36e758ad0e22916015038108d36
---
.../SwipeableRow/SwipeableListViewDataSource.js | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/Libraries/Experimental/SwipeableRow/SwipeableListViewDataSource.js b/Libraries/Experimental/SwipeableRow/SwipeableListViewDataSource.js
index 506b434160d98e..4fc44549688e2b 100644
--- a/Libraries/Experimental/SwipeableRow/SwipeableListViewDataSource.js
+++ b/Libraries/Experimental/SwipeableRow/SwipeableListViewDataSource.js
@@ -88,6 +88,16 @@ class SwipeableListViewDataSource {
return Object.keys(this._dataBlob)[0];
}
+ getLastRowID(): ?string {
+ if (this.rowIdentities && this.rowIdentities.length) {
+ const lastSection = this.rowIdentities[this.rowIdentities.length - 1];
+ if (lastSection && lastSection.length) {
+ return lastSection[lastSection.length - 1];
+ }
+ }
+ return Object.keys(this._dataBlob)[this._dataBlob.length - 1];
+ }
+
setOpenRowID(rowID: string): SwipeableListViewDataSource {
this._previousOpenRowID = this._openRowID;
this._openRowID = rowID;
From 266ab7a0061c11c4da7ccde9e0d461c0d7331563 Mon Sep 17 00:00:00 2001
From: Chris Zheng
Date: Sun, 12 Nov 2017 13:30:13 -0800
Subject: [PATCH 25/50] Pass scriptURL to RCTTestRunner
Summary:
Pass scriptURL to RCTTestRunner.
If the scriptURL passed to RCTTestRunner is not nil, then RCTTestRunner will use it.
else, RCTTestRunner will use whatever it has before.
Differential Revision: D6215186
fbshipit-source-id: c3a5643021d60579fc8e60a69de150f6a4a39237
---
Libraries/RCTTest/RCTTestRunner.h | 8 +++++---
Libraries/RCTTest/RCTTestRunner.m | 8 +++++++-
.../RCTRootViewIntegrationTests.m | 2 +-
.../RNTesterIntegrationTests/RNTesterIntegrationTests.m | 2 +-
RNTester/RNTesterIntegrationTests/RNTesterSnapshotTests.m | 2 +-
5 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/Libraries/RCTTest/RCTTestRunner.h b/Libraries/RCTTest/RCTTestRunner.h
index b1edad6a201811..9a50e94b2c9f13 100644
--- a/Libraries/RCTTest/RCTTestRunner.h
+++ b/Libraries/RCTTest/RCTTestRunner.h
@@ -32,10 +32,11 @@
* Use the RCTInitRunnerForApp macro for typical usage. See FBSnapshotTestCase.h for more information
* on how to configure the snapshotting system.
*/
-#define RCTInitRunnerForApp(app__, moduleProvider__) \
+#define RCTInitRunnerForApp(app__, moduleProvider__, scriptURL__) \
[[RCTTestRunner alloc] initWithApp:(app__) \
referenceDirectory:@FB_REFERENCE_IMAGE_DIR \
- moduleProvider:(moduleProvider__)]
+ moduleProvider:(moduleProvider__) \
+ scriptURL: scriptURL__]
@protocol RCTBridgeModule;
@class RCTBridge;
@@ -68,7 +69,8 @@
*/
- (instancetype)initWithApp:(NSString *)app
referenceDirectory:(NSString *)referenceDirectory
- moduleProvider:(RCTBridgeModuleListProvider)block NS_DESIGNATED_INITIALIZER;
+ moduleProvider:(RCTBridgeModuleListProvider)block
+ scriptURL:(NSURL *)scriptURL NS_DESIGNATED_INITIALIZER;
/**
* Simplest runTest function simply mounts the specified JS module with no
diff --git a/Libraries/RCTTest/RCTTestRunner.m b/Libraries/RCTTest/RCTTestRunner.m
index cb79087c321da7..836d7bb7762117 100644
--- a/Libraries/RCTTest/RCTTestRunner.m
+++ b/Libraries/RCTTest/RCTTestRunner.m
@@ -31,6 +31,7 @@ @implementation RCTTestRunner
- (instancetype)initWithApp:(NSString *)app
referenceDirectory:(NSString *)referenceDirectory
moduleProvider:(RCTBridgeModuleListProvider)block
+ scriptURL:(NSURL *)scriptURL
{
RCTAssertParam(app);
RCTAssertParam(referenceDirectory);
@@ -46,7 +47,12 @@ - (instancetype)initWithApp:(NSString *)app
_testController.referenceImagesDirectory = referenceDirectory;
_moduleProvider = [block copy];
_appPath = app;
- [self updateScript];
+
+ if (scriptURL != nil) {
+ _scriptURL = scriptURL;
+ } else {
+ [self updateScript];
+ }
}
return self;
}
diff --git a/RNTester/RNTesterIntegrationTests/RCTRootViewIntegrationTests.m b/RNTester/RNTesterIntegrationTests/RCTRootViewIntegrationTests.m
index 364a2b956202d4..fc015278359fdd 100644
--- a/RNTester/RNTesterIntegrationTests/RCTRootViewIntegrationTests.m
+++ b/RNTester/RNTesterIntegrationTests/RCTRootViewIntegrationTests.m
@@ -117,7 +117,7 @@ @implementation RCTRootViewIntegrationTests
- (void)setUp
{
- _runner = RCTInitRunnerForApp(@"IntegrationTests/RCTRootViewIntegrationTestApp", nil);
+ _runner = RCTInitRunnerForApp(@"IntegrationTests/RCTRootViewIntegrationTestApp", nil, nil);
}
#pragma mark Logic Tests
diff --git a/RNTester/RNTesterIntegrationTests/RNTesterIntegrationTests.m b/RNTester/RNTesterIntegrationTests/RNTesterIntegrationTests.m
index 6a09c5e1ee5930..005d0e899ee371 100644
--- a/RNTester/RNTesterIntegrationTests/RNTesterIntegrationTests.m
+++ b/RNTester/RNTesterIntegrationTests/RNTesterIntegrationTests.m
@@ -37,7 +37,7 @@ @implementation RNTesterIntegrationTests
- (void)setUp
{
- _runner = RCTInitRunnerForApp(@"IntegrationTests/IntegrationTestsApp", nil);
+ _runner = RCTInitRunnerForApp(@"IntegrationTests/IntegrationTestsApp", nil, nil);
_runner.recordMode = NO;
}
diff --git a/RNTester/RNTesterIntegrationTests/RNTesterSnapshotTests.m b/RNTester/RNTesterIntegrationTests/RNTesterSnapshotTests.m
index 8b369d4c01f7bc..4ba1e184a42422 100644
--- a/RNTester/RNTesterIntegrationTests/RNTesterSnapshotTests.m
+++ b/RNTester/RNTesterIntegrationTests/RNTesterSnapshotTests.m
@@ -24,7 +24,7 @@ @implementation RNTesterSnapshotTests
- (void)setUp
{
- _runner = RCTInitRunnerForApp(@"RNTester/js/RNTesterApp.ios", nil);
+ _runner = RCTInitRunnerForApp(@"RNTester/js/RNTesterApp.ios", nil, nil);
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 11) {
_runner.testSuffix = @"-iOS11";
} else if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10) {
From 28d5d6baf1e6ac52e8672a653f56c3898e4e11d2 Mon Sep 17 00:00:00 2001
From: Kevin Gozali
Date: Sun, 12 Nov 2017 22:48:56 -0800
Subject: [PATCH 26/50] Fix asset resolver url handling
Summary:
1. file:// may get prepended to an http:// source URL during dev mode, making an invalid URL
2. the logic to detect `isLoadedFromFileSystem()` should've checked for file:// protocol to not get confused by http:// URL
Reviewed By: zahanm
Differential Revision: D6307187
fbshipit-source-id: e7e7a41bf721dd0601b0c1877e278e1e435ef5e2
---
Libraries/Image/AssetSourceResolver.js | 2 +-
Libraries/Image/resolveAssetSource.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Libraries/Image/AssetSourceResolver.js b/Libraries/Image/AssetSourceResolver.js
index a240b5af71601e..4b4e4117f35cba 100644
--- a/Libraries/Image/AssetSourceResolver.js
+++ b/Libraries/Image/AssetSourceResolver.js
@@ -73,7 +73,7 @@ class AssetSourceResolver {
}
isLoadedFromFileSystem(): boolean {
- return !!this.jsbundleUrl;
+ return !!(this.jsbundleUrl && this.jsbundleUrl.startsWith('file://'));
}
canLoadFromEmbeddedBundledLocation(): boolean {
diff --git a/Libraries/Image/resolveAssetSource.js b/Libraries/Image/resolveAssetSource.js
index aba63045e4d18b..bb46279af4df3c 100644
--- a/Libraries/Image/resolveAssetSource.js
+++ b/Libraries/Image/resolveAssetSource.js
@@ -43,7 +43,7 @@ function _coerceLocalScriptURL(scriptURL: ?string): ?string {
return null;
}
scriptURL = scriptURL.substring(0, scriptURL.lastIndexOf('/') + 1);
- if (!scriptURL.startsWith('file://')) {
+ if (!scriptURL.includes('://')) {
// Add file protocol in case we have an absolute file path and not a URL.
// This shouldn't really be necessary. scriptURL should be a URL.
scriptURL = 'file://' + scriptURL;
From 4894ac430d6df1118ce48f644fd8cf5bfce6344f Mon Sep 17 00:00:00 2001
From: Dmitry Zakharov
Date: Tue, 14 Nov 2017 04:35:52 -0800
Subject: [PATCH 27/50] Remove splitting to BridgeCorePackage and
ReactNativePackage.
Reviewed By: kathryngray
Differential Revision: D6286129
fbshipit-source-id: 8d75e610291402ccbffb137ce46e64d11826b950
---
.../com/facebook/react/BridgeCorePackage.java | 132 ------------------
.../facebook/react/CoreModulesPackage.java | 81 ++---------
.../facebook/react/ReactInstanceManager.java | 10 +-
.../react/ReactNativeCorePackage.java | 114 ---------------
4 files changed, 17 insertions(+), 320 deletions(-)
delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/BridgeCorePackage.java
delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/ReactNativeCorePackage.java
diff --git a/ReactAndroid/src/main/java/com/facebook/react/BridgeCorePackage.java b/ReactAndroid/src/main/java/com/facebook/react/BridgeCorePackage.java
deleted file mode 100644
index 7554c223f1c49e..00000000000000
--- a/ReactAndroid/src/main/java/com/facebook/react/BridgeCorePackage.java
+++ /dev/null
@@ -1,132 +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.
- */
-
-package com.facebook.react;
-
-import com.facebook.react.bridge.ModuleSpec;
-import com.facebook.react.bridge.NativeModule;
-import com.facebook.react.bridge.ReactApplicationContext;
-import com.facebook.react.module.annotations.ReactModuleList;
-import com.facebook.react.module.model.ReactModuleInfoProvider;
-import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
-import com.facebook.react.modules.core.DeviceEventManagerModule;
-import com.facebook.react.modules.core.ExceptionsManagerModule;
-import com.facebook.react.modules.core.HeadlessJsTaskSupportModule;
-import com.facebook.react.modules.core.Timing;
-import com.facebook.react.modules.debug.SourceCodeModule;
-import com.facebook.react.modules.deviceinfo.DeviceInfoModule;
-import com.facebook.react.modules.systeminfo.AndroidInfoModule;
-import java.util.ArrayList;
-import java.util.List;
-import javax.inject.Provider;
-
-/**
- * Package defining core framework modules for basic JS interop.
- * It should be used for modules that are always necessary for interacting with
- * JS, not for modules that provide RN specific functionality
- */
-@ReactModuleList(
- nativeModules = {
- AndroidInfoModule.class,
- DeviceEventManagerModule.class,
- ExceptionsManagerModule.class,
- HeadlessJsTaskSupportModule.class,
- SourceCodeModule.class,
- Timing.class,
- DeviceInfoModule.class,
- }
-)
-/* package */ class BridgeCorePackage extends LazyReactPackage {
-
- private final ReactInstanceManager mReactInstanceManager;
- private final DefaultHardwareBackBtnHandler mHardwareBackBtnHandler;
-
- BridgeCorePackage(
- ReactInstanceManager reactInstanceManager,
- DefaultHardwareBackBtnHandler hardwareBackBtnHandler) {
- mReactInstanceManager = reactInstanceManager;
- mHardwareBackBtnHandler = hardwareBackBtnHandler;
- }
-
- @Override
- public List getNativeModules(final ReactApplicationContext reactContext) {
- List moduleSpecList = new ArrayList<>();
-
- moduleSpecList.add(
- ModuleSpec.nativeModuleSpec(
- AndroidInfoModule.class,
- new Provider() {
- @Override
- public NativeModule get() {
- return new AndroidInfoModule();
- }
- }));
- moduleSpecList.add(
- ModuleSpec.nativeModuleSpec(
- DeviceEventManagerModule.class,
- new Provider() {
- @Override
- public NativeModule get() {
- return new DeviceEventManagerModule(reactContext, mHardwareBackBtnHandler);
- }
- }));
- moduleSpecList.add(
- ModuleSpec.nativeModuleSpec(
- ExceptionsManagerModule.class,
- new Provider() {
- @Override
- public NativeModule get() {
- return new ExceptionsManagerModule(mReactInstanceManager.getDevSupportManager());
- }
- }));
- moduleSpecList.add(
- ModuleSpec.nativeModuleSpec(
- HeadlessJsTaskSupportModule.class,
- new Provider() {
- @Override
- public NativeModule get() {
- return new HeadlessJsTaskSupportModule(reactContext);
- }
- }));
- moduleSpecList.add(
- ModuleSpec.nativeModuleSpec(
- SourceCodeModule.class,
- new Provider() {
- @Override
- public NativeModule get() {
- return new SourceCodeModule(reactContext);
- }
- }));
- moduleSpecList.add(
- ModuleSpec.nativeModuleSpec(
- Timing.class,
- new Provider() {
- @Override
- public NativeModule get() {
- return new Timing(reactContext, mReactInstanceManager.getDevSupportManager());
- }
- }));
- moduleSpecList.add(
- ModuleSpec.nativeModuleSpec(
- DeviceInfoModule.class,
- new Provider() {
- @Override
- public NativeModule get() {
- return new DeviceInfoModule(reactContext);
- }
- }));
-
- return moduleSpecList;
- }
-
- @Override
- public ReactModuleInfoProvider getReactModuleInfoProvider() {
- return LazyReactPackage.getReactModuleInfoProviderViaReflection(this);
- }
-}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/CoreModulesPackage.java b/ReactAndroid/src/main/java/com/facebook/react/CoreModulesPackage.java
index 293ca70b58a4e0..7b0ac3253bf402 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/CoreModulesPackage.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/CoreModulesPackage.java
@@ -18,9 +18,6 @@
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactMarker;
-import com.facebook.react.common.build.ReactBuildConfig;
-import com.facebook.react.devsupport.JSCHeapCapture;
-import com.facebook.react.devsupport.JSCSamplingProfiler;
import com.facebook.react.module.annotations.ReactModuleList;
import com.facebook.react.module.model.ReactModuleInfoProvider;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
@@ -28,7 +25,6 @@
import com.facebook.react.modules.core.ExceptionsManagerModule;
import com.facebook.react.modules.core.HeadlessJsTaskSupportModule;
import com.facebook.react.modules.core.Timing;
-import com.facebook.react.modules.debug.AnimationsDebugModule;
import com.facebook.react.modules.debug.SourceCodeModule;
import com.facebook.react.modules.deviceinfo.DeviceInfoModule;
import com.facebook.react.modules.systeminfo.AndroidInfoModule;
@@ -36,35 +32,24 @@
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.systrace.Systrace;
-import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import javax.annotation.Nullable;
import javax.inject.Provider;
+
/**
- * This module should be removed following the completion of an experiment into splitting this into
- * three modules to allow for more light-weight instantiations of the bridge without UIManager
- * The core modules are now in BridgeCorePackage
- * The debug modules are now in DebugCorePackage
- * The UI manager is in ReactNativeCorePackage
- *
- * Package defining core framework modules (e.g. UIManager). It should be used for modules that
- * require special integration with other framework parts (e.g. with the list of packages to load
- * view managers from).
+ * This is the basic module to support React Native. The debug modules are now in DebugCorePackage.
*/
@ReactModuleList(
nativeModules = {
AndroidInfoModule.class,
- AnimationsDebugModule.class,
DeviceEventManagerModule.class,
+ DeviceInfoModule.class,
ExceptionsManagerModule.class,
HeadlessJsTaskSupportModule.class,
SourceCodeModule.class,
Timing.class,
UIManagerModule.class,
- DeviceInfoModule.class,
- // Debug only
- JSCHeapCapture.class,
- JSCSamplingProfiler.class,
}
)
/* package */ class CoreModulesPackage extends LazyReactPackage implements ReactPackageLogger {
@@ -90,9 +75,7 @@
@Override
public List getNativeModules(final ReactApplicationContext reactContext) {
- List moduleSpecList = new ArrayList<>();
-
- moduleSpecList.add(
+ return Arrays.asList(
ModuleSpec.nativeModuleSpec(
AndroidInfoModule.class,
new Provider() {
@@ -100,18 +83,7 @@ public List getNativeModules(final ReactApplicationContext reactCont
public NativeModule get() {
return new AndroidInfoModule();
}
- }));
- moduleSpecList.add(
- ModuleSpec.nativeModuleSpec(
- AnimationsDebugModule.class,
- new Provider() {
- @Override
- public NativeModule get() {
- return new AnimationsDebugModule(
- reactContext, mReactInstanceManager.getDevSupportManager().getDevSettings());
- }
- }));
- moduleSpecList.add(
+ }),
ModuleSpec.nativeModuleSpec(
DeviceEventManagerModule.class,
new Provider() {
@@ -119,8 +91,7 @@ public NativeModule get() {
public NativeModule get() {
return new DeviceEventManagerModule(reactContext, mHardwareBackBtnHandler);
}
- }));
- moduleSpecList.add(
+ }),
ModuleSpec.nativeModuleSpec(
ExceptionsManagerModule.class,
new Provider() {
@@ -128,8 +99,7 @@ public NativeModule get() {
public NativeModule get() {
return new ExceptionsManagerModule(mReactInstanceManager.getDevSupportManager());
}
- }));
- moduleSpecList.add(
+ }),
ModuleSpec.nativeModuleSpec(
HeadlessJsTaskSupportModule.class,
new Provider() {
@@ -137,8 +107,7 @@ public NativeModule get() {
public NativeModule get() {
return new HeadlessJsTaskSupportModule(reactContext);
}
- }));
- moduleSpecList.add(
+ }),
ModuleSpec.nativeModuleSpec(
SourceCodeModule.class,
new Provider() {
@@ -146,8 +115,7 @@ public NativeModule get() {
public NativeModule get() {
return new SourceCodeModule(reactContext);
}
- }));
- moduleSpecList.add(
+ }),
ModuleSpec.nativeModuleSpec(
Timing.class,
new Provider() {
@@ -155,8 +123,7 @@ public NativeModule get() {
public NativeModule get() {
return new Timing(reactContext, mReactInstanceManager.getDevSupportManager());
}
- }));
- moduleSpecList.add(
+ }),
ModuleSpec.nativeModuleSpec(
UIManagerModule.class,
new Provider() {
@@ -164,8 +131,7 @@ public NativeModule get() {
public NativeModule get() {
return createUIManager(reactContext);
}
- }));
- moduleSpecList.add(
+ }),
ModuleSpec.nativeModuleSpec(
DeviceInfoModule.class,
new Provider() {
@@ -174,29 +140,6 @@ public NativeModule get() {
return new DeviceInfoModule(reactContext);
}
}));
-
- if (ReactBuildConfig.DEBUG) {
- moduleSpecList.add(
- ModuleSpec.nativeModuleSpec(
- JSCHeapCapture.class,
- new Provider() {
- @Override
- public NativeModule get() {
- return new JSCHeapCapture(reactContext);
- }
- }));
- moduleSpecList.add(
- ModuleSpec.nativeModuleSpec(
- JSCSamplingProfiler.class,
- new Provider() {
- @Override
- public NativeModule get() {
- return new JSCSamplingProfiler(reactContext);
- }
- }));
- }
-
- return moduleSpecList;
}
@Override
diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java
index aa317e7503bb4a..0e06dd854916b9 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java
@@ -272,16 +272,16 @@ public static ReactInstanceManagerBuilder builder() {
mMinNumShakes = minNumShakes;
synchronized (mPackages) {
PrinterHolder.getPrinter().logMessage(ReactDebugOverlayTags.RN_CORE, "RNCore: Use Split Packages");
- mPackages.add(new BridgeCorePackage(this, mBackBtnHandler));
- if (mUseDeveloperSupport) {
- mPackages.add(new DebugCorePackage());
- }
mPackages.add(
- new ReactNativeCorePackage(
+ new CoreModulesPackage(
this,
+ mBackBtnHandler,
mUIImplementationProvider,
mLazyViewManagersEnabled,
mMinTimeLeftInFrameForNonBatchedOperationMs));
+ if (mUseDeveloperSupport) {
+ mPackages.add(new DebugCorePackage());
+ }
mPackages.addAll(packages);
}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactNativeCorePackage.java b/ReactAndroid/src/main/java/com/facebook/react/ReactNativeCorePackage.java
deleted file mode 100644
index 0e7b36edbf7b11..00000000000000
--- a/ReactAndroid/src/main/java/com/facebook/react/ReactNativeCorePackage.java
+++ /dev/null
@@ -1,114 +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.
- */
-
-package com.facebook.react;
-
-import static com.facebook.react.bridge.ReactMarkerConstants.CREATE_UI_MANAGER_MODULE_END;
-import static com.facebook.react.bridge.ReactMarkerConstants.CREATE_UI_MANAGER_MODULE_START;
-
-import com.facebook.react.bridge.ModuleSpec;
-import com.facebook.react.bridge.NativeModule;
-import com.facebook.react.bridge.ReactApplicationContext;
-import com.facebook.react.bridge.ReactMarker;
-import com.facebook.react.module.annotations.ReactModuleList;
-import com.facebook.react.module.model.ReactModuleInfoProvider;
-import com.facebook.react.uimanager.UIImplementationProvider;
-import com.facebook.react.uimanager.UIManagerModule;
-import com.facebook.react.uimanager.ViewManager;
-import com.facebook.systrace.Systrace;
-import java.util.Collections;
-import java.util.List;
-import javax.annotation.Nullable;
-import javax.inject.Provider;
-
-/**
- * Package defining core framework modules for initializing ReactNative (e.g. UIManager). It should be used for modules that
- * require special integration with other framework parts (e.g. with the list of packages to load
- * view managers from).
- */
-@ReactModuleList(
- nativeModules = {
- UIManagerModule.class,
- }
-)
-public class ReactNativeCorePackage extends LazyReactPackage {
-
- private final ReactInstanceManager mReactInstanceManager;
- private final UIImplementationProvider mUIImplementationProvider;
- private final boolean mLazyViewManagersEnabled;
- private final int mMinTimeLeftInFrameForNonBatchedOperationMs;
-
- public ReactNativeCorePackage(
- ReactInstanceManager reactInstanceManager,
- UIImplementationProvider uiImplementationProvider,
- boolean lazyViewManagersEnabled,
- int minTimeLeftInFrameForNonBatchedOperationMs) {
- mReactInstanceManager = reactInstanceManager;
- mUIImplementationProvider = uiImplementationProvider;
- mLazyViewManagersEnabled = lazyViewManagersEnabled;
- mMinTimeLeftInFrameForNonBatchedOperationMs = minTimeLeftInFrameForNonBatchedOperationMs;
- }
-
- @Override
- public List getNativeModules(final ReactApplicationContext reactContext) {
- return Collections.singletonList(
- ModuleSpec.nativeModuleSpec(
- UIManagerModule.class,
- new Provider() {
- @Override
- public NativeModule get() {
- return createUIManager(reactContext);
- }
- }));
- }
-
- @Override
- public ReactModuleInfoProvider getReactModuleInfoProvider() {
- // This has to be done via reflection or we break open source.
- ReactModuleInfoProvider reactModuleInfoProvider =
- LazyReactPackage.getReactModuleInfoProviderViaReflection(this);
- return reactModuleInfoProvider;
- }
-
- private UIManagerModule createUIManager(final ReactApplicationContext reactContext) {
- ReactMarker.logMarker(CREATE_UI_MANAGER_MODULE_START);
- Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "createUIManagerModule");
- try {
- if (mLazyViewManagersEnabled) {
- UIManagerModule.ViewManagerResolver viewManagerResolver =
- new UIManagerModule.ViewManagerResolver() {
- @Override
- public @Nullable ViewManager getViewManager(String viewManagerName) {
- return mReactInstanceManager.createViewManager(viewManagerName);
- }
-
- @Override
- public List getViewManagerNames() {
- return mReactInstanceManager.getViewManagerNames();
- }
- };
-
- return new UIManagerModule(
- reactContext,
- viewManagerResolver,
- mUIImplementationProvider,
- mMinTimeLeftInFrameForNonBatchedOperationMs);
- } else {
- return new UIManagerModule(
- reactContext,
- mReactInstanceManager.createAllViewManagers(reactContext),
- mUIImplementationProvider,
- mMinTimeLeftInFrameForNonBatchedOperationMs);
- }
- } finally {
- Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
- ReactMarker.logMarker(CREATE_UI_MANAGER_MODULE_END);
- }
- }
-}
From 053776338ea44c31f3671cb4502853da0c88e55a Mon Sep 17 00:00:00 2001
From: Dmitry Zakharov
Date: Tue, 14 Nov 2017 05:43:55 -0800
Subject: [PATCH 28/50] Cleanup ReactInstanceManager
Reviewed By: kathryngray
Differential Revision: D6296922
fbshipit-source-id: 2fbf11f09a3c25ff3e7c222edc2e01b81e687943
---
.../facebook/react/ReactInstanceManager.java | 85 +++++++++----------
1 file changed, 39 insertions(+), 46 deletions(-)
diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java
index 0e06dd854916b9..6bb07f30f1d958 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java
@@ -152,42 +152,12 @@ public interface ReactInstanceEventListener {
// Identifies whether the instance manager destroy function is in process,
// while true any spawned create thread should wait for proper clean up before initializing
private volatile Boolean mHasStartedDestroying = false;
- private final UIImplementationProvider mUIImplementationProvider;
private final MemoryPressureRouter mMemoryPressureRouter;
private final @Nullable NativeModuleCallExceptionHandler mNativeModuleCallExceptionHandler;
private final boolean mLazyNativeModulesEnabled;
- private final boolean mLazyViewManagersEnabled;
private final boolean mDelayViewManagerClassLoadsEnabled;
private final boolean mUseSeparateUIBackgroundThread;
private final int mMinNumShakes;
- private final int mMinTimeLeftInFrameForNonBatchedOperationMs;
-
- private final ReactInstanceDevCommandsHandler mDevInterface =
- new ReactInstanceDevCommandsHandler() {
-
- @Override
- public void onReloadWithJSDebugger(JavaJSExecutor.Factory jsExecutorFactory) {
- ReactInstanceManager.this.onReloadWithJSDebugger(jsExecutorFactory);
- }
-
- @Override
- public void onJSBundleLoadedFromServer() {
- ReactInstanceManager.this.onJSBundleLoadedFromServer();
- }
-
- @Override
- public void toggleElementInspector() {
- ReactInstanceManager.this.toggleElementInspector();
- }
- };
-
- private final DefaultHardwareBackBtnHandler mBackBtnHandler =
- new DefaultHardwareBackBtnHandler() {
- @Override
- public void invokeDefaultOnBackPressed() {
- ReactInstanceManager.this.invokeDefaultOnBackPressed();
- }
- };
private class ReactContextInitParams {
private final JavaScriptExecutorFactory mJsExecutorFactory;
@@ -251,34 +221,38 @@ public static ReactInstanceManagerBuilder builder() {
mPackages = new ArrayList<>();
mInitFunctions = new ArrayList<>();
mUseDeveloperSupport = useDeveloperSupport;
- mDevSupportManager = DevSupportManagerFactory.create(
- applicationContext,
- mDevInterface,
- mJSMainModulePath,
- useDeveloperSupport,
- redBoxHandler,
- devBundleDownloadListener,
- minNumShakes);
+ mDevSupportManager =
+ DevSupportManagerFactory.create(
+ applicationContext,
+ createDevInterface(),
+ mJSMainModulePath,
+ useDeveloperSupport,
+ redBoxHandler,
+ devBundleDownloadListener,
+ minNumShakes);
mBridgeIdleDebugListener = bridgeIdleDebugListener;
mLifecycleState = initialLifecycleState;
- mUIImplementationProvider = uiImplementationProvider;
mMemoryPressureRouter = new MemoryPressureRouter(applicationContext);
mNativeModuleCallExceptionHandler = nativeModuleCallExceptionHandler;
mLazyNativeModulesEnabled = lazyNativeModulesEnabled;
- mLazyViewManagersEnabled = lazyViewManagersEnabled;
mDelayViewManagerClassLoadsEnabled = delayViewManagerClassLoadsEnabled;
- mMinTimeLeftInFrameForNonBatchedOperationMs = minTimeLeftInFrameForNonBatchedOperationMs;
mUseSeparateUIBackgroundThread = useSeparateUIBackgroundThread;
mMinNumShakes = minNumShakes;
synchronized (mPackages) {
- PrinterHolder.getPrinter().logMessage(ReactDebugOverlayTags.RN_CORE, "RNCore: Use Split Packages");
+ PrinterHolder.getPrinter()
+ .logMessage(ReactDebugOverlayTags.RN_CORE, "RNCore: Use Split Packages");
mPackages.add(
new CoreModulesPackage(
this,
- mBackBtnHandler,
- mUIImplementationProvider,
- mLazyViewManagersEnabled,
- mMinTimeLeftInFrameForNonBatchedOperationMs));
+ new DefaultHardwareBackBtnHandler() {
+ @Override
+ public void invokeDefaultOnBackPressed() {
+ ReactInstanceManager.this.invokeDefaultOnBackPressed();
+ }
+ },
+ uiImplementationProvider,
+ lazyViewManagersEnabled,
+ minTimeLeftInFrameForNonBatchedOperationMs));
if (mUseDeveloperSupport) {
mPackages.add(new DebugCorePackage());
}
@@ -292,6 +266,25 @@ public static ReactInstanceManagerBuilder builder() {
}
}
+ private ReactInstanceDevCommandsHandler createDevInterface() {
+ return new ReactInstanceDevCommandsHandler() {
+ @Override
+ public void onReloadWithJSDebugger(JavaJSExecutor.Factory jsExecutorFactory) {
+ ReactInstanceManager.this.onReloadWithJSDebugger(jsExecutorFactory);
+ }
+
+ @Override
+ public void onJSBundleLoadedFromServer() {
+ ReactInstanceManager.this.onJSBundleLoadedFromServer();
+ }
+
+ @Override
+ public void toggleElementInspector() {
+ ReactInstanceManager.this.toggleElementInspector();
+ }
+ };
+ }
+
public DevSupportManager getDevSupportManager() {
return mDevSupportManager;
}
From 4f886a29a1234c967deae2354bbc5092e0e6595e Mon Sep 17 00:00:00 2001
From: Dmitry Zakharov
Date: Tue, 14 Nov 2017 06:39:22 -0800
Subject: [PATCH 29/50] Remove
android_react_native_perf.use_separate_ui_bg_thread experiment.
Reviewed By: AaaChiuuu
Differential Revision: D6313250
fbshipit-source-id: 583a729a157a2053827631a43e38917753e78477
---
.../facebook/react/ReactInstanceManager.java | 16 +---------
.../react/ReactInstanceManagerBuilder.java | 8 -----
.../com/facebook/react/ReactRootView.java | 2 +-
.../react/bridge/CatalystInstanceImpl.java | 4 ---
.../facebook/react/bridge/ReactContext.java | 30 -------------------
.../bridge/queue/ReactQueueConfiguration.java | 3 --
.../queue/ReactQueueConfigurationImpl.java | 28 ++---------------
.../queue/ReactQueueConfigurationSpec.java | 29 ------------------
.../react/uimanager/UIManagerModule.java | 6 ++--
.../react/views/modal/ReactModalHostView.java | 2 +-
.../jni/react/jni/CatalystInstanceImpl.cpp | 15 ++--------
.../main/jni/react/jni/CatalystInstanceImpl.h | 2 --
.../jni/react/jni/ModuleRegistryBuilder.cpp | 19 ++----------
.../jni/react/jni/ModuleRegistryBuilder.h | 3 +-
14 files changed, 16 insertions(+), 151 deletions(-)
diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java
index 6bb07f30f1d958..a891b327d20028 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java
@@ -156,7 +156,6 @@ public interface ReactInstanceEventListener {
private final @Nullable NativeModuleCallExceptionHandler mNativeModuleCallExceptionHandler;
private final boolean mLazyNativeModulesEnabled;
private final boolean mDelayViewManagerClassLoadsEnabled;
- private final boolean mUseSeparateUIBackgroundThread;
private final int mMinNumShakes;
private class ReactContextInitParams {
@@ -204,7 +203,6 @@ public static ReactInstanceManagerBuilder builder() {
boolean lazyViewManagersEnabled,
boolean delayViewManagerClassLoadsEnabled,
@Nullable DevBundleDownloadListener devBundleDownloadListener,
- boolean useSeparateUIBackgroundThread,
int minNumShakes,
int minTimeLeftInFrameForNonBatchedOperationMs) {
Log.d(ReactConstants.TAG, "ReactInstanceManager.ctor()");
@@ -236,7 +234,6 @@ public static ReactInstanceManagerBuilder builder() {
mNativeModuleCallExceptionHandler = nativeModuleCallExceptionHandler;
mLazyNativeModulesEnabled = lazyNativeModulesEnabled;
mDelayViewManagerClassLoadsEnabled = delayViewManagerClassLoadsEnabled;
- mUseSeparateUIBackgroundThread = useSeparateUIBackgroundThread;
mMinNumShakes = minNumShakes;
synchronized (mPackages) {
PrinterHolder.getPrinter()
@@ -995,15 +992,6 @@ public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
}
});
- if (mUseSeparateUIBackgroundThread) {
- reactContext.runOnUiBackgroundQueueThread(
- new Runnable() {
- @Override
- public void run() {
- Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
- }
- });
- }
}
private void attachRootViewToInstance(
@@ -1080,9 +1068,7 @@ private ReactApplicationContext createReactContext(
? mNativeModuleCallExceptionHandler
: mDevSupportManager;
CatalystInstanceImpl.Builder catalystInstanceBuilder = new CatalystInstanceImpl.Builder()
- .setReactQueueConfigurationSpec(mUseSeparateUIBackgroundThread ?
- ReactQueueConfigurationSpec.createWithSeparateUIBackgroundThread() :
- ReactQueueConfigurationSpec.createDefault())
+ .setReactQueueConfigurationSpec(ReactQueueConfigurationSpec.createDefault())
.setJSExecutor(jsExecutor)
.setRegistry(nativeModuleRegistry)
.setJSBundleLoader(jsBundleLoader)
diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java
index 2fbaaa2b80c339..f7fc31e2c62d77 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java
@@ -46,7 +46,6 @@ public class ReactInstanceManagerBuilder {
private boolean mDelayViewManagerClassLoadsEnabled;
private @Nullable DevBundleDownloadListener mDevBundleDownloadListener;
private @Nullable JavaScriptExecutorFactory mJavaScriptExecutorFactory;
- private boolean mUseSeparateUIBackgroundThread;
private int mMinNumShakes = 1;
private int mMinTimeLeftInFrameForNonBatchedOperationMs = -1;
@@ -214,12 +213,6 @@ public ReactInstanceManagerBuilder setDevBundleDownloadListener(
return this;
}
- public ReactInstanceManagerBuilder setUseSeparateUIBackgroundThread(
- boolean useSeparateUIBackgroundThread) {
- mUseSeparateUIBackgroundThread = useSeparateUIBackgroundThread;
- return this;
- }
-
public ReactInstanceManagerBuilder setMinNumShakes(int minNumShakes) {
mMinNumShakes = minNumShakes;
return this;
@@ -286,7 +279,6 @@ public ReactInstanceManager build() {
mLazyViewManagersEnabled,
mDelayViewManagerClassLoadsEnabled,
mDevBundleDownloadListener,
- mUseSeparateUIBackgroundThread,
mMinNumShakes,
mMinTimeLeftInFrameForNonBatchedOperationMs);
}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java b/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java
index 87c5f5902468e0..05cfc8d776ed80 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java
@@ -330,7 +330,7 @@ private void updateRootLayoutSpecs(final int widthMeasureSpec, final int heightM
}
final ReactContext reactApplicationContext = mReactInstanceManager.getCurrentReactContext();
if (reactApplicationContext != null) {
- reactApplicationContext.runUIBackgroundRunnable(
+ reactApplicationContext.runOnNativeModulesQueueThread(
new GuardedRunnable(reactApplicationContext) {
@Override
public void runGuarded() {
diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java
index f9b883c3532a2f..7afc565c2f9418 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java
@@ -83,7 +83,6 @@ public String toString() {
private final NativeModuleRegistry mNativeModuleRegistry;
private final NativeModuleCallExceptionHandler mNativeModuleCallExceptionHandler;
private final MessageQueueThread mNativeModulesQueueThread;
- private final @Nullable MessageQueueThread mUIBackgroundQueueThread;
private boolean mInitialized = false;
private volatile boolean mAcceptCalls = false;
@@ -114,7 +113,6 @@ private CatalystInstanceImpl(
mJSBundleLoader = jsBundleLoader;
mNativeModuleCallExceptionHandler = nativeModuleCallExceptionHandler;
mNativeModulesQueueThread = mReactQueueConfiguration.getNativeModulesQueueThread();
- mUIBackgroundQueueThread = mReactQueueConfiguration.getUIBackgroundQueueThread();
mTraceListener = new JSProfilerTraceListener(this);
Log.d(ReactConstants.TAG, "Initializing React Xplat Bridge before initializeBridge");
@@ -123,7 +121,6 @@ private CatalystInstanceImpl(
jsExecutor,
mReactQueueConfiguration.getJSQueueThread(),
mNativeModulesQueueThread,
- mUIBackgroundQueueThread,
mNativeModuleRegistry.getJavaModules(this),
mNativeModuleRegistry.getCxxModules());
Log.d(ReactConstants.TAG, "Initializing React Xplat Bridge after initializeBridge");
@@ -191,7 +188,6 @@ private native void initializeBridge(
JavaScriptExecutor jsExecutor,
MessageQueueThread jsQueue,
MessageQueueThread moduleQueue,
- MessageQueueThread uiBackgroundQueue,
Collection javaModules,
Collection cxxModules);
diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java
index 4148889d3bf2aa..85959c84547055 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java
@@ -44,7 +44,6 @@ public class ReactContext extends ContextWrapper {
private @Nullable CatalystInstance mCatalystInstance;
private @Nullable LayoutInflater mInflater;
private @Nullable MessageQueueThread mUiMessageQueueThread;
- private @Nullable MessageQueueThread mUiBackgroundMessageQueueThread;
private @Nullable MessageQueueThread mNativeModulesMessageQueueThread;
private @Nullable MessageQueueThread mJSMessageQueueThread;
private @Nullable NativeModuleCallExceptionHandler mNativeModuleCallExceptionHandler;
@@ -69,7 +68,6 @@ public void initializeWithInstance(CatalystInstance catalystInstance) {
ReactQueueConfiguration queueConfig = catalystInstance.getReactQueueConfiguration();
mUiMessageQueueThread = queueConfig.getUIQueueThread();
- mUiBackgroundMessageQueueThread = queueConfig.getUIBackgroundQueueThread();
mNativeModulesMessageQueueThread = queueConfig.getNativeModulesQueueThread();
mJSMessageQueueThread = queueConfig.getJSQueueThread();
}
@@ -269,14 +267,6 @@ public void runOnUiQueueThread(Runnable runnable) {
Assertions.assertNotNull(mUiMessageQueueThread).runOnQueue(runnable);
}
- public void assertOnUiBackgroundQueueThread() {
- Assertions.assertNotNull(mUiBackgroundMessageQueueThread).assertIsOnThread();
- }
-
- public void runOnUiBackgroundQueueThread(Runnable runnable) {
- Assertions.assertNotNull(mUiBackgroundMessageQueueThread).runOnQueue(runnable);
- }
-
public void assertOnNativeModulesQueueThread() {
Assertions.assertNotNull(mNativeModulesMessageQueueThread).assertIsOnThread();
}
@@ -305,26 +295,6 @@ public void runOnJSQueueThread(Runnable runnable) {
Assertions.assertNotNull(mJSMessageQueueThread).runOnQueue(runnable);
}
- public boolean hasUIBackgroundRunnableThread() {
- return mUiBackgroundMessageQueueThread != null;
- }
-
- public void assertOnUIBackgroundOrNativeModulesThread() {
- if (mUiBackgroundMessageQueueThread == null) {
- assertOnNativeModulesQueueThread();
- } else {
- assertOnUiBackgroundQueueThread();
- }
- }
-
- public void runUIBackgroundRunnable(Runnable runnable) {
- if (mUiBackgroundMessageQueueThread == null) {
- runOnNativeModulesQueueThread(runnable);
- } else {
- runOnUiBackgroundQueueThread(runnable);
- }
- }
-
/**
* Passes the given exception to the current
* {@link com.facebook.react.bridge.NativeModuleCallExceptionHandler} if one exists, rethrowing
diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/queue/ReactQueueConfiguration.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/queue/ReactQueueConfiguration.java
index 68a42a82f1fabc..b5b44a9a2c51a0 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/bridge/queue/ReactQueueConfiguration.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/queue/ReactQueueConfiguration.java
@@ -9,7 +9,6 @@
package com.facebook.react.bridge.queue;
-import javax.annotation.Nullable;
/**
* Specifies which {@link MessageQueueThread}s must be used to run the various contexts of
@@ -22,8 +21,6 @@
*/
public interface ReactQueueConfiguration {
MessageQueueThread getUIQueueThread();
- @Nullable
- MessageQueueThread getUIBackgroundQueueThread();
MessageQueueThread getNativeModulesQueueThread();
MessageQueueThread getJSQueueThread();
void destroy();
diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/queue/ReactQueueConfigurationImpl.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/queue/ReactQueueConfigurationImpl.java
index 05b37c5977f29c..60d7e0eb164302 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/bridge/queue/ReactQueueConfigurationImpl.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/queue/ReactQueueConfigurationImpl.java
@@ -9,8 +9,6 @@
package com.facebook.react.bridge.queue;
-import javax.annotation.Nullable;
-
import java.util.Map;
import android.os.Looper;
@@ -20,17 +18,14 @@
public class ReactQueueConfigurationImpl implements ReactQueueConfiguration {
private final MessageQueueThreadImpl mUIQueueThread;
- private final @Nullable MessageQueueThreadImpl mUIBackgroundQueueThread;
private final MessageQueueThreadImpl mNativeModulesQueueThread;
private final MessageQueueThreadImpl mJSQueueThread;
private ReactQueueConfigurationImpl(
- MessageQueueThreadImpl uiQueueThread,
- @Nullable MessageQueueThreadImpl uiBackgroundQueueThread,
- MessageQueueThreadImpl nativeModulesQueueThread,
- MessageQueueThreadImpl jsQueueThread) {
+ MessageQueueThreadImpl uiQueueThread,
+ MessageQueueThreadImpl nativeModulesQueueThread,
+ MessageQueueThreadImpl jsQueueThread) {
mUIQueueThread = uiQueueThread;
- mUIBackgroundQueueThread = uiBackgroundQueueThread;
mNativeModulesQueueThread = nativeModulesQueueThread;
mJSQueueThread = jsQueueThread;
}
@@ -40,11 +35,6 @@ public MessageQueueThread getUIQueueThread() {
return mUIQueueThread;
}
- @Override
- public @Nullable MessageQueueThread getUIBackgroundQueueThread() {
- return mUIBackgroundQueueThread;
- }
-
@Override
public MessageQueueThread getNativeModulesQueueThread() {
return mNativeModulesQueueThread;
@@ -60,10 +50,6 @@ public MessageQueueThread getJSQueueThread() {
* is destroyed so that we shut down the proper queue threads.
*/
public void destroy() {
- if (mUIBackgroundQueueThread != null &&
- mUIBackgroundQueueThread.getLooper() != Looper.getMainLooper()) {
- mUIBackgroundQueueThread.quitSynchronous();
- }
if (mNativeModulesQueueThread.getLooper() != Looper.getMainLooper()) {
mNativeModulesQueueThread.quitSynchronous();
}
@@ -94,16 +80,8 @@ public static ReactQueueConfigurationImpl create(
MessageQueueThreadImpl.create(spec.getNativeModulesQueueThreadSpec(), exceptionHandler);
}
- MessageQueueThreadImpl uiBackgroundThread =
- specsToThreads.get(spec.getUIBackgroundQueueThreadSpec());
- if (uiBackgroundThread == null && spec.getUIBackgroundQueueThreadSpec() != null) {
- uiBackgroundThread =
- MessageQueueThreadImpl.create(spec.getUIBackgroundQueueThreadSpec(), exceptionHandler);
- }
-
return new ReactQueueConfigurationImpl(
uiThread,
- uiBackgroundThread,
nativeModulesThread,
jsThread);
}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/queue/ReactQueueConfigurationSpec.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/queue/ReactQueueConfigurationSpec.java
index 6b23bfd716431d..a112f217c608de 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/bridge/queue/ReactQueueConfigurationSpec.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/queue/ReactQueueConfigurationSpec.java
@@ -25,23 +25,16 @@ public class ReactQueueConfigurationSpec {
private static final long LEGACY_STACK_SIZE_BYTES = 2000000;
- private final @Nullable MessageQueueThreadSpec mUIBackgroundQueueThreadSpec;
private final MessageQueueThreadSpec mNativeModulesQueueThreadSpec;
private final MessageQueueThreadSpec mJSQueueThreadSpec;
private ReactQueueConfigurationSpec(
- @Nullable MessageQueueThreadSpec uiBackgroundQueueThreadSpec,
MessageQueueThreadSpec nativeModulesQueueThreadSpec,
MessageQueueThreadSpec jsQueueThreadSpec) {
- mUIBackgroundQueueThreadSpec = uiBackgroundQueueThreadSpec;
mNativeModulesQueueThreadSpec = nativeModulesQueueThreadSpec;
mJSQueueThreadSpec = jsQueueThreadSpec;
}
- public @Nullable MessageQueueThreadSpec getUIBackgroundQueueThreadSpec() {
- return mUIBackgroundQueueThreadSpec;
- }
-
public MessageQueueThreadSpec getNativeModulesQueueThreadSpec() {
return mNativeModulesQueueThreadSpec;
}
@@ -64,32 +57,11 @@ public static ReactQueueConfigurationSpec createDefault() {
.build();
}
- public static ReactQueueConfigurationSpec createWithSeparateUIBackgroundThread() {
- MessageQueueThreadSpec spec = Build.VERSION.SDK_INT < 21 ?
- MessageQueueThreadSpec.newBackgroundThreadSpec("native_modules", LEGACY_STACK_SIZE_BYTES) :
- MessageQueueThreadSpec.newBackgroundThreadSpec("native_modules");
- return builder()
- .setJSQueueThreadSpec(MessageQueueThreadSpec.newBackgroundThreadSpec("js"))
- .setNativeModulesQueueThreadSpec(spec)
- .setUIBackgroundQueueThreadSpec(
- MessageQueueThreadSpec.newUIBackgroundTreadSpec("ui_background"))
- .build();
- }
-
public static class Builder {
- private @Nullable MessageQueueThreadSpec mUIBackgroundQueueSpec;
private @Nullable MessageQueueThreadSpec mNativeModulesQueueSpec;
private @Nullable MessageQueueThreadSpec mJSQueueSpec;
- public Builder setUIBackgroundQueueThreadSpec(MessageQueueThreadSpec spec) {
- Assertions.assertCondition(
- mUIBackgroundQueueSpec == null,
- "Setting UI background queue multiple times!");
- mUIBackgroundQueueSpec = spec;
- return this;
- }
-
public Builder setNativeModulesQueueThreadSpec(MessageQueueThreadSpec spec) {
Assertions.assertCondition(
mNativeModulesQueueSpec == null,
@@ -106,7 +78,6 @@ public Builder setJSQueueThreadSpec(MessageQueueThreadSpec spec) {
public ReactQueueConfigurationSpec build() {
return new ReactQueueConfigurationSpec(
- mUIBackgroundQueueSpec,
Assertions.assertNotNull(mNativeModulesQueueSpec),
Assertions.assertNotNull(mJSQueueSpec));
}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java
index 1591127cf97479..7becf4ad48f221 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java
@@ -305,7 +305,7 @@ public int addRootVi
new SizeMonitoringFrameLayout.OnSizeChangedListener() {
@Override
public void onSizeChanged(final int width, final int height, int oldW, int oldH) {
- reactApplicationContext.runUIBackgroundRunnable(
+ reactApplicationContext.runOnNativeModulesQueueThread(
new GuardedRunnable(reactApplicationContext) {
@Override
public void runGuarded() {
@@ -325,7 +325,7 @@ public void removeRootView(int rootViewTag) {
}
public void updateNodeSize(int nodeViewTag, int newWidth, int newHeight) {
- getReactApplicationContext().assertOnUIBackgroundOrNativeModulesThread();
+ getReactApplicationContext().assertOnNativeModulesQueueThread();
mUIImplementation.updateNodeSize(nodeViewTag, newWidth, newHeight);
}
@@ -344,7 +344,7 @@ public void setViewLocalData(final int tag, final Object data) {
reactApplicationContext.assertOnUiQueueThread();
- reactApplicationContext.runUIBackgroundRunnable(
+ reactApplicationContext.runOnNativeModulesQueueThread(
new GuardedRunnable(reactApplicationContext) {
@Override
public void runGuarded() {
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java
index 705e455020418d..674c6ef80675b6 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java
@@ -306,7 +306,7 @@ protected void onSizeChanged(final int w, final int h, int oldw, int oldh) {
if (getChildCount() > 0) {
final int viewTag = getChildAt(0).getId();
ReactContext reactContext = (ReactContext) getContext();
- reactContext.runUIBackgroundRunnable(
+ reactContext.runOnNativeModulesQueueThread(
new GuardedRunnable(reactContext) {
@Override
public void runGuarded() {
diff --git a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp
index abac4d1b19e081..7b136f0d0cdf14 100644
--- a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp
+++ b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp
@@ -89,9 +89,6 @@ CatalystInstanceImpl::~CatalystInstanceImpl() {
if (moduleMessageQueue_ != NULL) {
moduleMessageQueue_->quitSynchronous();
}
- if (uiBackgroundMessageQueue_ != NULL) {
- uiBackgroundMessageQueue_->quitSynchronous();
- }
}
void CatalystInstanceImpl::registerNatives() {
@@ -119,15 +116,11 @@ void CatalystInstanceImpl::initializeBridge(
JavaScriptExecutorHolder* jseh,
jni::alias_ref jsQueue,
jni::alias_ref nativeModulesQueue,
- jni::alias_ref uiBackgroundQueue,
jni::alias_ref::javaobject> javaModules,
jni::alias_ref::javaobject> cxxModules) {
// TODO mhorowitz: how to assert here?
// Assertions.assertCondition(mBridge == null, "initializeBridge should be called once");
moduleMessageQueue_ = std::make_shared(nativeModulesQueue);
- if (uiBackgroundQueue.get() != nullptr) {
- uiBackgroundMessageQueue_ = std::make_shared(uiBackgroundQueue);
- }
// This used to be:
//
@@ -150,13 +143,12 @@ void CatalystInstanceImpl::initializeBridge(
std::weak_ptr(instance_),
javaModules,
cxxModules,
- moduleMessageQueue_,
- uiBackgroundMessageQueue_));
+ moduleMessageQueue_));
instance_->initializeBridge(
folly::make_unique(
callback,
- uiBackgroundMessageQueue_ != NULL ? uiBackgroundMessageQueue_ : moduleMessageQueue_),
+ moduleMessageQueue_),
jseh->getExecutorFactory(),
folly::make_unique(jsQueue),
moduleRegistry_);
@@ -169,8 +161,7 @@ void CatalystInstanceImpl::extendNativeModules(
std::weak_ptr(instance_),
javaModules,
cxxModules,
- moduleMessageQueue_,
- uiBackgroundMessageQueue_));
+ moduleMessageQueue_));
}
void CatalystInstanceImpl::jniSetSourceURL(const std::string& sourceURL) {
diff --git a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h
index 8a94c8cc9f3807..5f7b1be15157e6 100644
--- a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h
+++ b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h
@@ -46,7 +46,6 @@ class CatalystInstanceImpl : public jni::HybridClass {
JavaScriptExecutorHolder* jseh,
jni::alias_ref jsQueue,
jni::alias_ref moduleQueue,
- jni::alias_ref uiBackgroundQueue,
jni::alias_ref::javaobject> javaModules,
jni::alias_ref::javaobject> cxxModules);
@@ -79,7 +78,6 @@ class CatalystInstanceImpl : public jni::HybridClass {
std::shared_ptr instance_;
std::shared_ptr moduleRegistry_;
std::shared_ptr moduleMessageQueue_;
- std::shared_ptr uiBackgroundMessageQueue_;
};
}}
diff --git a/ReactAndroid/src/main/jni/react/jni/ModuleRegistryBuilder.cpp b/ReactAndroid/src/main/jni/react/jni/ModuleRegistryBuilder.cpp
index 9706a43dc1c18d..eb204dd3ee91b3 100644
--- a/ReactAndroid/src/main/jni/react/jni/ModuleRegistryBuilder.cpp
+++ b/ReactAndroid/src/main/jni/react/jni/ModuleRegistryBuilder.cpp
@@ -33,25 +33,12 @@ std::vector> buildNativeModuleList(
std::weak_ptr winstance,
jni::alias_ref::javaobject> javaModules,
jni::alias_ref::javaobject> cxxModules,
- std::shared_ptr moduleMessageQueue,
- std::shared_ptr uiBackgroundMessageQueue) {
+ std::shared_ptr moduleMessageQueue) {
std::vector> modules;
if (javaModules) {
for (const auto& jm : *javaModules) {
- std::string name = jm->getName();
- if (uiBackgroundMessageQueue != NULL &&
- // This is techinically a hack. Perhaps we should bind the specific queue to the module
- // in the module holder or wrapper.
- // TODO expose as module configuration option
- (name == "UIManager" ||
- name == "NativeAnimatedModule" ||
- name == "FBFacebookReactNavigator")) {
- modules.emplace_back(folly::make_unique(
- winstance, jm, uiBackgroundMessageQueue));
- } else {
- modules.emplace_back(folly::make_unique(
- winstance, jm, moduleMessageQueue));
- }
+ modules.emplace_back(folly::make_unique(
+ winstance, jm, moduleMessageQueue));
}
}
if (cxxModules) {
diff --git a/ReactAndroid/src/main/jni/react/jni/ModuleRegistryBuilder.h b/ReactAndroid/src/main/jni/react/jni/ModuleRegistryBuilder.h
index 6e31adc898d3bd..3a8cc09258e00f 100644
--- a/ReactAndroid/src/main/jni/react/jni/ModuleRegistryBuilder.h
+++ b/ReactAndroid/src/main/jni/react/jni/ModuleRegistryBuilder.h
@@ -27,7 +27,6 @@ std::vector> buildNativeModuleList(
std::weak_ptr winstance,
jni::alias_ref::javaobject> javaModules,
jni::alias_ref::javaobject> cxxModules,
- std::shared_ptr moduleMessageQueue,
- std::shared_ptr uiBackgroundMessageQueue);
+ std::shared_ptr moduleMessageQueue);
}
}
From cfa2bbf2f692d0bc5600d7e369a9a91272930ca6 Mon Sep 17 00:00:00 2001
From: Dmitry Zakharov
Date: Tue, 14 Nov 2017 09:23:28 -0800
Subject: [PATCH 30/50] Remove minNumShakes from ReactInstaneManager
Reviewed By: kathryngray
Differential Revision: D6313521
fbshipit-source-id: ffef1f96fbec88cdcc7597fa81505aee59e10bb8
---
.../main/java/com/facebook/react/ReactInstanceManager.java | 6 ------
1 file changed, 6 deletions(-)
diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java
index a891b327d20028..d9f4975fb20ca2 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java
@@ -156,7 +156,6 @@ public interface ReactInstanceEventListener {
private final @Nullable NativeModuleCallExceptionHandler mNativeModuleCallExceptionHandler;
private final boolean mLazyNativeModulesEnabled;
private final boolean mDelayViewManagerClassLoadsEnabled;
- private final int mMinNumShakes;
private class ReactContextInitParams {
private final JavaScriptExecutorFactory mJsExecutorFactory;
@@ -234,7 +233,6 @@ public static ReactInstanceManagerBuilder builder() {
mNativeModuleCallExceptionHandler = nativeModuleCallExceptionHandler;
mLazyNativeModulesEnabled = lazyNativeModulesEnabled;
mDelayViewManagerClassLoadsEnabled = delayViewManagerClassLoadsEnabled;
- mMinNumShakes = minNumShakes;
synchronized (mPackages) {
PrinterHolder.getPrinter()
.logMessage(ReactDebugOverlayTags.RN_CORE, "RNCore: Use Split Packages");
@@ -827,10 +825,6 @@ public LifecycleState getLifecycleState() {
return mLifecycleState;
}
- public int getMinNumShakes() {
- return mMinNumShakes;
- }
-
@ThreadConfined(UI)
private void onReloadWithJSDebugger(JavaJSExecutor.Factory jsExecutorFactory) {
Log.d(ReactConstants.TAG, "ReactInstanceManager.onReloadWithJSDebugger()");
From 58edf024a1ed3a71ef04f124546ee97496b6502f Mon Sep 17 00:00:00 2001
From: Wei Yeh
Date: Tue, 14 Nov 2017 10:08:23 -0800
Subject: [PATCH 31/50] Fix typo in SafeArea documentation
Reviewed By: shergin
Differential Revision: D6316656
fbshipit-source-id: 12d37f9d8ad2481b7f6685c8d675ce84234bd814
---
Libraries/Components/SafeAreaView/SafeAreaView.ios.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Libraries/Components/SafeAreaView/SafeAreaView.ios.js b/Libraries/Components/SafeAreaView/SafeAreaView.ios.js
index 35ae985a4810f1..73336990a7a6f6 100644
--- a/Libraries/Components/SafeAreaView/SafeAreaView.ios.js
+++ b/Libraries/Components/SafeAreaView/SafeAreaView.ios.js
@@ -24,7 +24,7 @@ type Props = ViewProps & {
/**
* Renders nested content and automatically applies paddings reflect the portion of the view
* that is not covered by navigation bars, tab bars, toolbars, and other ancestor views.
- * Moreover, and most importantly, Safe Area's paddings feflect physical limitation of the screen,
+ * Moreover, and most importantly, Safe Area's paddings reflect physical limitation of the screen,
* such as rounded corners or camera notches (aka sensor housing area on iPhone X).
*/
class SafeAreaView extends React.Component {
From 3e4cf0e8d278d3c9fdb4d3aec981a257baf4d24d Mon Sep 17 00:00:00 2001
From: allengleyzer
Date: Tue, 14 Nov 2017 10:50:52 -0800
Subject: [PATCH 32/50] Added progress updates for all XMLHttpRequest upload
types
Summary:
Previously, only form-data request bodies emitted upload progress updates. Now,
other request body types will also emit updates.
Addresses issues:
https://github.com/facebook/react-native/issues/15724
https://github.com/facebook/react-native/issues/11853
This is a bug fix for functionality that's missing on Android. These events are already working correctly on iOS.
Run the following code on Android, and ensure that events are being sent:
```
const fileUri = 'file:///my_file.dat';
const url = 'http://my_post_url.com/';
const xhr = new XMLHttpRequest();
xhr.upload.onprogress = (event) => {
console.log('progress: ' + event.loaded + ' / ' + event.total);
}
xhr.onreadystatechange = () => {if (xhr.readyState === 4) console.log('done');}
console.log('start');
xhr.open('POST', url);
xhr.send({ uri: fileUri }); // sending a file (wasn't sending progress)
xhr.send("some big string"); // sending a string (wasn't sending progress)
const formData = new FormData(); formData.set('test', 'data');
xhr.send(formData); // sending form data (was already working)
```
[ANDROID] [BUGFIX] [XMLHttpRequest] - Added progress updates for all XMLHttpRequest upload types
Previously, only form-data request bodies emitted upload progress updates. Now,
other request body types will also emit updates.
Addresses issues:
https://github.com/facebook/react-native/issues/15724
https://github.com/facebook/react-native/issues/11853
Closes https://github.com/facebook/react-native/pull/16541
Differential Revision: D6325252
Pulled By: hramos
fbshipit-source-id: 4fe617216293e6f451e2a1af4fa872e8f56d4f93
---
.../modules/network/NetworkingModule.java | 63 ++++++++++---------
.../modules/network/NetworkingModuleTest.java | 9 ++-
2 files changed, 42 insertions(+), 30 deletions(-)
diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java
index 297cd1ef4ff2fc..58fd605459397c 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java
@@ -235,8 +235,9 @@ public void onProgress(long bytesWritten, long contentLength, boolean done) {
String contentEncoding = requestHeaders.get(CONTENT_ENCODING_HEADER_NAME);
requestBuilder.headers(requestHeaders);
+ RequestBody requestBody;
if (data == null) {
- requestBuilder.method(method, RequestBodyUtil.getEmptyBody(method));
+ requestBody = RequestBodyUtil.getEmptyBody(method);
} else if (data.hasKey(REQUEST_BODY_KEY_STRING)) {
if (contentType == null) {
ResponseUtil.onRequestError(
@@ -249,14 +250,13 @@ public void onProgress(long bytesWritten, long contentLength, boolean done) {
String body = data.getString(REQUEST_BODY_KEY_STRING);
MediaType contentMediaType = MediaType.parse(contentType);
if (RequestBodyUtil.isGzipEncoding(contentEncoding)) {
- RequestBody requestBody = RequestBodyUtil.createGzip(contentMediaType, body);
+ requestBody = RequestBodyUtil.createGzip(contentMediaType, body);
if (requestBody == null) {
ResponseUtil.onRequestError(eventEmitter, requestId, "Failed to gzip request body", null);
return;
}
- requestBuilder.method(method, requestBody);
} else {
- requestBuilder.method(method, RequestBody.create(contentMediaType, body));
+ requestBody = RequestBody.create(contentMediaType, body);
}
} else if (data.hasKey(REQUEST_BODY_KEY_BASE64)) {
if (contentType == null) {
@@ -269,9 +269,7 @@ public void onProgress(long bytesWritten, long contentLength, boolean done) {
}
String base64String = data.getString(REQUEST_BODY_KEY_BASE64);
MediaType contentMediaType = MediaType.parse(contentType);
- requestBuilder.method(
- method,
- RequestBody.create(contentMediaType, ByteString.decodeBase64(base64String)));
+ requestBody = RequestBody.create(contentMediaType, ByteString.decodeBase64(base64String));
} else if (data.hasKey(REQUEST_BODY_KEY_URI)) {
if (contentType == null) {
ResponseUtil.onRequestError(
@@ -292,9 +290,7 @@ public void onProgress(long bytesWritten, long contentLength, boolean done) {
null);
return;
}
- requestBuilder.method(
- method,
- RequestBodyUtil.create(MediaType.parse(contentType), fileInputStream));
+ requestBody = RequestBodyUtil.create(MediaType.parse(contentType), fileInputStream);
} else if (data.hasKey(REQUEST_BODY_KEY_FORMDATA)) {
if (contentType == null) {
contentType = "multipart/form-data";
@@ -305,28 +301,16 @@ public void onProgress(long bytesWritten, long contentLength, boolean done) {
if (multipartBuilder == null) {
return;
}
-
- requestBuilder.method(
- method,
- RequestBodyUtil.createProgressRequest(
- multipartBuilder.build(),
- new ProgressListener() {
- long last = System.nanoTime();
-
- @Override
- public void onProgress(long bytesWritten, long contentLength, boolean done) {
- long now = System.nanoTime();
- if (done || shouldDispatch(now, last)) {
- ResponseUtil.onDataSend(eventEmitter, requestId, bytesWritten, contentLength);
- last = now;
- }
- }
- }));
+ requestBody = multipartBuilder.build();
} else {
// Nothing in data payload, at least nothing we could understand anyway.
- requestBuilder.method(method, RequestBodyUtil.getEmptyBody(method));
+ requestBody = RequestBodyUtil.getEmptyBody(method);
}
+ requestBuilder.method(
+ method,
+ wrapRequestBodyWithProgressEmitter(requestBody, eventEmitter, requestId));
+
addRequest(requestId);
client.newCall(requestBuilder.build()).enqueue(
new Callback() {
@@ -394,6 +378,29 @@ public void onResponse(Call call, Response response) throws IOException {
});
}
+ private RequestBody wrapRequestBodyWithProgressEmitter(
+ final RequestBody requestBody,
+ final RCTDeviceEventEmitter eventEmitter,
+ final int requestId) {
+ if(requestBody == null) {
+ return null;
+ }
+ return RequestBodyUtil.createProgressRequest(
+ requestBody,
+ new ProgressListener() {
+ long last = System.nanoTime();
+
+ @Override
+ public void onProgress(long bytesWritten, long contentLength, boolean done) {
+ long now = System.nanoTime();
+ if (done || shouldDispatch(now, last)) {
+ ResponseUtil.onDataSend(eventEmitter, requestId, bytesWritten, contentLength);
+ last = now;
+ }
+ }
+ });
+ }
+
private void readWithProgress(
RCTDeviceEventEmitter eventEmitter,
int requestId,
diff --git a/ReactAndroid/src/test/java/com/facebook/react/modules/network/NetworkingModuleTest.java b/ReactAndroid/src/test/java/com/facebook/react/modules/network/NetworkingModuleTest.java
index 7b512bc252a5ed..8ad39cd16e2070 100644
--- a/ReactAndroid/src/test/java/com/facebook/react/modules/network/NetworkingModuleTest.java
+++ b/ReactAndroid/src/test/java/com/facebook/react/modules/network/NetworkingModuleTest.java
@@ -200,6 +200,10 @@ public WritableMap answer(InvocationOnMock invocation) throws Throwable {
@Test
public void testSuccessfulPostRequest() throws Exception {
+ RCTDeviceEventEmitter emitter = mock(RCTDeviceEventEmitter.class);
+ ReactApplicationContext context = mock(ReactApplicationContext.class);
+ when(context.getJSModule(any(Class.class))).thenReturn(emitter);
+
OkHttpClient httpClient = mock(OkHttpClient.class);
when(httpClient.newCall(any(Request.class))).thenAnswer(new Answer