mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Compare commits
11
Commits
main
...
0.37-stable
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
890342ed88 | ||
|
|
1ecc24a4eb | ||
|
|
4d0ce9022a | ||
|
|
0b27d21455 | ||
|
|
cedf4dd617 | ||
|
|
1142efae44 | ||
|
|
2d3fcf245b | ||
|
|
d282168548 | ||
|
|
a69581a073 | ||
|
|
4b1731727a | ||
|
|
4f50fc8392 |
@@ -11,20 +11,41 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const invariant = require('fbjs/lib/invariant');
|
||||
const NativeEventEmitter = require('NativeEventEmitter');
|
||||
const KeyboardObserver = require('NativeModules').KeyboardObserver;
|
||||
const dismissKeyboard = require('dismissKeyboard');
|
||||
const KeyboardEventEmitter = new NativeEventEmitter(KeyboardObserver);
|
||||
|
||||
type KeyboardEventName =
|
||||
| 'keyboardWillShow'
|
||||
| 'keyboardDidShow'
|
||||
| 'keyboardWillHide'
|
||||
| 'keyboardDidHide'
|
||||
| 'keyboardWillChangeFrame'
|
||||
| 'keyboardDidChangeFrame';
|
||||
|
||||
type KeyboardEventData = {
|
||||
endCoordinates: {
|
||||
width: number,
|
||||
height: number,
|
||||
screenX: number,
|
||||
screenY: number,
|
||||
},
|
||||
};
|
||||
|
||||
type KeyboardEventListener = (e: KeyboardEventData) => void;
|
||||
|
||||
// The following object exists for documentation purposes
|
||||
// Actual work happens in
|
||||
// https://github.com/facebook/react-native/blob/master/Libraries/EventEmitter/NativeEventEmitter.js
|
||||
|
||||
/**
|
||||
* `Keyboard` component to control keyboard events.
|
||||
* `Keyboard` module to control keyboard events.
|
||||
*
|
||||
* ### Usage
|
||||
*
|
||||
* The Keyboard component allows you to listen for native events and react to them, as
|
||||
* The Keyboard module allows you to listen for native events and react to them, as
|
||||
* well as make changes to the keyboard, like dismissing it.
|
||||
*
|
||||
*```
|
||||
@@ -60,16 +81,17 @@ const KeyboardEventEmitter = new NativeEventEmitter(KeyboardObserver);
|
||||
* }
|
||||
*```
|
||||
*/
|
||||
module.exports = {
|
||||
|
||||
let Keyboard = {
|
||||
/**
|
||||
* The `addListener` function connects a JavaScript function to an identified native
|
||||
* keyboard notification event.
|
||||
*
|
||||
* This function then returns the reference to the listener.
|
||||
*
|
||||
* @param {string} nativeEvent The `nativeEvent` is the string that identifies the event you're listening for. This
|
||||
* @param {string} eventName The `nativeEvent` is the string that identifies the event you're listening for. This
|
||||
*can be any of the following:
|
||||
*
|
||||
* - `keyboardWillShow`
|
||||
* - `keyboardDidShow`
|
||||
* - `keyboardWillHide`
|
||||
@@ -77,10 +99,20 @@ module.exports = {
|
||||
* - `keyboardWillChangeFrame`
|
||||
* - `keyboardDidChangeFrame`
|
||||
*
|
||||
* @param {function} jsFunction function to be called when the event fires.
|
||||
* @param {function} callback function to be called when the event fires.
|
||||
*/
|
||||
addListener (nativeEvent: string, jsFunction: Function) {
|
||||
return KeyboardEventEmitter.addListener(nativeEvent, jsFunction);
|
||||
addListener(eventName: KeyboardEventName, callback: KeyboardEventListener) {
|
||||
invariant(false, 'Dummy method used for documentation');
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes a specific listener.
|
||||
*
|
||||
* @param {string} eventName The `nativeEvent` is the string that identifies the event you're listening for.
|
||||
* @param {function} callback function to be called when the event fires.
|
||||
*/
|
||||
removeListener(eventName: KeyboardEventName, callback: Function) {
|
||||
invariant(false, 'Dummy method used for documentation');
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -88,24 +120,21 @@ module.exports = {
|
||||
*
|
||||
* @param {string} eventType The native event string listeners are watching which will be removed.
|
||||
*/
|
||||
removeAllListeners (eventType: string) {
|
||||
KeyboardEventEmitter.removeAllListeners(eventType);
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes a specific subscription.
|
||||
*
|
||||
* @param {EmitterSubscription} subscription The subscription emitter to be removed.
|
||||
*/
|
||||
removeSubscription (subscription: Object) {
|
||||
KeyboardEventEmitter.removeSubscription(subscription);
|
||||
removeAllListeners(eventName: KeyboardEventName) {
|
||||
invariant(false, 'Dummy method used for documentation');
|
||||
},
|
||||
|
||||
/**
|
||||
* Dismisses the active keyboard and removes focus.
|
||||
*/
|
||||
dismiss () {
|
||||
dismissKeyboard();
|
||||
dismiss() {
|
||||
invariant(false, 'Dummy method used for documentation');
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Throw away the dummy object and reassign it to original module
|
||||
Keyboard = KeyboardEventEmitter;
|
||||
Keyboard.dismiss = dismissKeyboard;
|
||||
|
||||
module.exports = Keyboard;
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "React"
|
||||
s.version = package['version']
|
||||
s.version = "0.37.0"
|
||||
s.summary = package['description']
|
||||
s.description = <<-DESC
|
||||
React Native apps are built using the React JS
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
VERSION_NAME=1000.0.0-master
|
||||
VERSION_NAME=0.37.0
|
||||
GROUP=com.facebook.react
|
||||
|
||||
POM_NAME=ReactNative
|
||||
|
||||
@@ -54,6 +54,14 @@ def configureReactNativePom(def pom) {
|
||||
}
|
||||
}
|
||||
|
||||
if (JavaVersion.current().isJava8Compatible()) {
|
||||
allprojects {
|
||||
tasks.withType(Javadoc) {
|
||||
options.addStringOption('Xdoclint:none', '-quiet')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
afterEvaluate { project ->
|
||||
|
||||
task androidJavadoc(type: Javadoc) {
|
||||
@@ -84,8 +92,7 @@ afterEvaluate { project ->
|
||||
|
||||
artifacts {
|
||||
archives androidSourcesJar
|
||||
// TODO Make Javadoc generation work with Java 1.8, currently only works with 1.7
|
||||
// archives androidJavadocJar
|
||||
archives androidJavadocJar
|
||||
}
|
||||
|
||||
version = VERSION_NAME
|
||||
|
||||
@@ -8,10 +8,50 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var execSync = require('child_process').execSync;
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var yeoman = require('yeoman-generator');
|
||||
var semver = require('semver')
|
||||
var utils = require('../generator-utils');
|
||||
var yeoman = require('yeoman-generator');
|
||||
|
||||
// Use Yarn if available, it's much faster than the npm client.
|
||||
// Return the version of yarn installed on the system, null if yarn is not available.
|
||||
function getYarnVersionIfAvailable() {
|
||||
let yarnVersion;
|
||||
try {
|
||||
// execSync returns a Buffer -> convert to string
|
||||
if (process.platform.startsWith('win')) {
|
||||
yarnVersion = (execSync('yarn --version').toString() || '').trim();
|
||||
} else {
|
||||
yarnVersion = (execSync('yarn --version 2>/dev/null').toString() || '').trim();
|
||||
}
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
// yarn < 0.16 has a 'missing manifest' bug
|
||||
try {
|
||||
if (semver.gte(yarnVersion, '0.16.0')) {
|
||||
return yarnVersion;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Cannot parse yarn version: ' + yarnVersion);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that 'react-native init' itself used yarn to install React Native.
|
||||
* When using an old global react-native-cli@1.0.0 (or older), we don't want
|
||||
* to install React Native with npm, and React + Jest with yarn.
|
||||
* Let's be safe and not mix yarn and npm in a single project.
|
||||
* @param projectDir e.g. /Users/martin/AwesomeApp
|
||||
*/
|
||||
function isGlobalCliUsingYarn(projectDir) {
|
||||
return fs.existsSync(path.join(projectDir, 'yarn.lock'));
|
||||
}
|
||||
|
||||
module.exports = yeoman.generators.NamedBase.extend({
|
||||
constructor: function() {
|
||||
@@ -36,6 +76,12 @@ module.exports = yeoman.generators.NamedBase.extend({
|
||||
type: Boolean,
|
||||
defaults: false
|
||||
});
|
||||
// Temporary option until yarn becomes stable.
|
||||
this.option('npm', {
|
||||
desc: 'Use the npm client, even if yarn is available.',
|
||||
type: Boolean,
|
||||
defaults: false
|
||||
});
|
||||
|
||||
// this passes command line arguments down to the composed generators
|
||||
var args = {args: arguments[0], options: this.options};
|
||||
@@ -112,12 +158,24 @@ module.exports = yeoman.generators.NamedBase.extend({
|
||||
return;
|
||||
}
|
||||
|
||||
this.npmInstall(`react@${reactVersion}`, { '--save': true, '--save-exact': true });
|
||||
const yarnVersion = (!this.options['npm']) && getYarnVersionIfAvailable() && isGlobalCliUsingYarn(this.destinationRoot());
|
||||
|
||||
console.log('Installing React...');
|
||||
if (yarnVersion) {
|
||||
execSync(`yarn add react@${reactVersion}`);
|
||||
} else {
|
||||
this.npmInstall(`react@${reactVersion}`, { '--save': true, '--save-exact': true });
|
||||
}
|
||||
if (!this.options['skip-jest']) {
|
||||
this.npmInstall(`jest babel-jest jest-react-native babel-preset-react-native react-test-renderer@${reactVersion}`.split(' '), {
|
||||
saveDev: true,
|
||||
'--save-exact': true
|
||||
});
|
||||
console.log('Installing Jest...');
|
||||
if (yarnVersion) {
|
||||
execSync(`yarn add jest babel-jest jest-react-native babel-preset-react-native react-test-renderer@${reactVersion} --dev --exact`);
|
||||
} else {
|
||||
this.npmInstall(`jest babel-jest jest-react-native babel-preset-react-native react-test-renderer@${reactVersion}`.split(' '), {
|
||||
saveDev: true,
|
||||
'--save-exact': true
|
||||
});
|
||||
}
|
||||
fs.writeFileSync(
|
||||
path.join(
|
||||
this.destinationRoot(),
|
||||
@@ -125,7 +183,6 @@ module.exports = yeoman.generators.NamedBase.extend({
|
||||
),
|
||||
'{\n"presets": ["react-native"]\n}'
|
||||
);
|
||||
|
||||
this.fs.copy(
|
||||
this.templatePath('__tests__'),
|
||||
this.destinationPath('__tests__'),
|
||||
@@ -133,7 +190,6 @@ module.exports = yeoman.generators.NamedBase.extend({
|
||||
nodir: false
|
||||
}
|
||||
);
|
||||
|
||||
var packageJSONPath = path.join(
|
||||
this.destinationRoot(),
|
||||
'package.json'
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-native",
|
||||
"version": "1000.0.0",
|
||||
"version": "0.37.0",
|
||||
"description": "A framework for building native apps using React",
|
||||
"license": "BSD-3-Clause",
|
||||
"repository": {
|
||||
@@ -223,4 +223,4 @@
|
||||
"eslint-plugin-flowtype": "^2.20.0",
|
||||
"eslint-plugin-react": "^6.4.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+70
-24
@@ -38,6 +38,7 @@
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var exec = require('child_process').exec;
|
||||
var execSync = require('child_process').execSync;
|
||||
var spawn = require('child_process').spawn;
|
||||
var chalk = require('chalk');
|
||||
var prompt = require('prompt');
|
||||
@@ -74,6 +75,33 @@ var REACT_NATIVE_PACKAGE_JSON_PATH = function() {
|
||||
);
|
||||
};
|
||||
|
||||
// Use Yarn if available, it's much faster than the npm client.
|
||||
// Return the version of yarn installed on the system, null if yarn is not available.
|
||||
function getYarnVersionIfAvailable() {
|
||||
let yarnVersion;
|
||||
try {
|
||||
// execSync returns a Buffer -> convert to string
|
||||
if (process.platform.startsWith('win')) {
|
||||
yarnVersion = (execSync('yarn --version').toString() || '').trim();
|
||||
} else {
|
||||
yarnVersion = (execSync('yarn --version 2>/dev/null').toString() || '').trim();
|
||||
}
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
// yarn < 0.16 has a 'missing manifest' bug
|
||||
try {
|
||||
if (semver.gte(yarnVersion, '0.16.0')) {
|
||||
return yarnVersion;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Cannot parse yarn version: ' + yarnVersion);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
checkForVersionArgument();
|
||||
|
||||
var cli;
|
||||
@@ -102,8 +130,8 @@ if (cli) {
|
||||
);
|
||||
process.exit(1);
|
||||
} else {
|
||||
if (!argv.verbose) console.log('This may take some time...');
|
||||
init(commands[1], argv.verbose, argv.version);
|
||||
const rnPackage = argv.version;
|
||||
init(commands[1], argv.verbose, rnPackage, argv.npm);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -117,7 +145,7 @@ if (cli) {
|
||||
}
|
||||
}
|
||||
|
||||
function validatePackageName(name) {
|
||||
function validateProjectName(name) {
|
||||
if (!name.match(/^[$A-Z_][0-9A-Z_$]*$/i)) {
|
||||
console.error(
|
||||
'"%s" is not a valid name for a project. Please use a valid identifier ' +
|
||||
@@ -137,17 +165,24 @@ function validatePackageName(name) {
|
||||
}
|
||||
}
|
||||
|
||||
function init(name, verbose, rnPackage) {
|
||||
validatePackageName(name);
|
||||
/**
|
||||
* @param name Project name, e.g. 'AwesomeApp'.
|
||||
* @param verbose If true, will run 'npm install' in verbose mode (for debugging).
|
||||
* @param rnPackage Version of React Native to install, e.g. '0.38.0'.
|
||||
* @param forceNpmClient If true, always use the npm command line client,
|
||||
* don't use yarn even if available.
|
||||
*/
|
||||
function init(name, verbose, rnPackage, forceNpmClient) {
|
||||
validateProjectName(name);
|
||||
|
||||
if (fs.existsSync(name)) {
|
||||
createAfterConfirmation(name, verbose, rnPackage);
|
||||
createAfterConfirmation(name, verbose, rnPackage, forceNpmClient);
|
||||
} else {
|
||||
createProject(name, verbose, rnPackage);
|
||||
createProject(name, verbose, rnPackage, forceNpmClient);
|
||||
}
|
||||
}
|
||||
|
||||
function createAfterConfirmation(name, verbose, rnPackage) {
|
||||
function createAfterConfirmation(name, verbose, rnPackage, forceNpmClient) {
|
||||
prompt.start();
|
||||
|
||||
var property = {
|
||||
@@ -160,7 +195,7 @@ function createAfterConfirmation(name, verbose, rnPackage) {
|
||||
|
||||
prompt.get(property, function (err, result) {
|
||||
if (result.yesno[0] === 'y') {
|
||||
createProject(name, verbose, rnPackage);
|
||||
createProject(name, verbose, rnPackage, forceNpmClient);
|
||||
} else {
|
||||
console.log('Project initialization canceled');
|
||||
process.exit();
|
||||
@@ -168,7 +203,7 @@ function createAfterConfirmation(name, verbose, rnPackage) {
|
||||
});
|
||||
}
|
||||
|
||||
function createProject(name, verbose, rnPackage) {
|
||||
function createProject(name, verbose, rnPackage, forceNpmClient) {
|
||||
var root = path.resolve(name);
|
||||
var projectName = path.basename(root);
|
||||
|
||||
@@ -192,20 +227,18 @@ function createProject(name, verbose, rnPackage) {
|
||||
fs.writeFileSync(path.join(root, 'package.json'), JSON.stringify(packageJson));
|
||||
process.chdir(root);
|
||||
|
||||
console.log('Installing react-native package from npm...');
|
||||
|
||||
if (verbose) {
|
||||
runVerbose(root, projectName, rnPackage);
|
||||
runVerbose(root, projectName, rnPackage, forceNpmClient);
|
||||
} else {
|
||||
run(root, projectName, rnPackage);
|
||||
run(root, projectName, rnPackage, forceNpmClient);
|
||||
}
|
||||
}
|
||||
|
||||
function getInstallPackage(rnPackage) {
|
||||
var packageToInstall = 'react-native';
|
||||
var valideSemver = semver.valid(rnPackage);
|
||||
if (valideSemver) {
|
||||
packageToInstall += '@' + valideSemver;
|
||||
var isValidSemver = semver.valid(rnPackage);
|
||||
if (isValidSemver) {
|
||||
packageToInstall += '@' + isValidSemver;
|
||||
} else if (rnPackage) {
|
||||
// for tar.gz or alternative paths
|
||||
packageToInstall = rnPackage;
|
||||
@@ -213,23 +246,36 @@ function getInstallPackage(rnPackage) {
|
||||
return packageToInstall;
|
||||
}
|
||||
|
||||
function run(root, projectName, rnPackage) {
|
||||
exec('npm install --save --save-exact ' + getInstallPackage(rnPackage), function(e, stdout, stderr) {
|
||||
if (e) {
|
||||
function run(root, projectName, rnPackage, forceNpmClient) {
|
||||
const yarnVersion = (!forceNpmClient) && getYarnVersionIfAvailable();
|
||||
let installCommand;
|
||||
if (yarnVersion) {
|
||||
console.log('Using yarn v' + yarnVersion);
|
||||
console.log('Installing ' + getInstallPackage(rnPackage) + '...');
|
||||
installCommand = 'yarn add ' + getInstallPackage(rnPackage) + ' --exact';
|
||||
} else {
|
||||
console.log('Installing ' + getInstallPackage(rnPackage) + ' from npm...');
|
||||
if (!forceNpmClient) {
|
||||
console.log('Consider installing yarn to make this faster: https://yarnpkg.com');
|
||||
}
|
||||
installCommand = 'npm install --save --save-exact ' + getInstallPackage(rnPackage);
|
||||
}
|
||||
exec(installCommand, function(err, stdout, stderr) {
|
||||
if (err) {
|
||||
console.log(stdout);
|
||||
console.error(stderr);
|
||||
console.error('`npm install --save --save-exact react-native` failed');
|
||||
console.error('Command `' + installCommand + '` failed.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
checkNodeVersion();
|
||||
|
||||
cli = require(CLI_MODULE_PATH());
|
||||
cli.init(root, projectName);
|
||||
});
|
||||
}
|
||||
|
||||
function runVerbose(root, projectName, rnPackage) {
|
||||
function runVerbose(root, projectName, rnPackage, forceNpmClient) {
|
||||
// Use npm client, yarn doesn't support --verbose yet
|
||||
console.log('Installing ' + getInstallPackage(rnPackage) + ' from npm. This might take a while...');
|
||||
var proc = spawn(/^win/.test(process.platform) ? 'npm.cmd' : 'npm', ['install', '--verbose', '--save', '--save-exact', getInstallPackage(rnPackage)], {stdio: 'inherit'});
|
||||
proc.on('close', function (code) {
|
||||
if (code !== 0) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-native-cli",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.0",
|
||||
"license": "BSD-3-Clause",
|
||||
"description": "The React Native CLI tools",
|
||||
"main": "index.js",
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
require(`shelljs/global`);
|
||||
|
||||
const buildBranch = process.env.CIRCLE_BRANCH;
|
||||
const requiredJavaVersion = `1.7`;
|
||||
|
||||
let branchVersion;
|
||||
if (buildBranch.indexOf(`-stable`) !== -1) {
|
||||
@@ -88,19 +87,6 @@ if (tagsWithVersion[0].indexOf(`-rc`) === -1) {
|
||||
}
|
||||
|
||||
// -------- Generating Android Artifacts with JavaDoc
|
||||
// Java -version outputs to stderr 0_o
|
||||
const javaVersion = exec(`java -version`).stderr;
|
||||
if (javaVersion.indexOf(requiredJavaVersion) === -1) {
|
||||
echo(`Java version must be 1.7.x in order to generate Javadoc. Check: java -version`);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Uncomment Javadoc generation
|
||||
if (sed(`-i`, `// archives androidJavadocJar`, `archives androidJavadocJar`, `ReactAndroid/release.gradle`).code) {
|
||||
echo(`Couldn't enable Javadoc generation`);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (exec(`./gradlew :ReactAndroid:installArchives`).code) {
|
||||
echo(`Couldn't generate artifacts`);
|
||||
exit(1);
|
||||
|
||||
Reference in New Issue
Block a user