Updates from 2015-07-27
This commit is contained in:
commit
2eb401a496
12
.flowconfig
12
.flowconfig
|
@ -9,11 +9,13 @@
|
|||
|
||||
# Ignore react-tools where there are overlaps, but don't ignore anything that
|
||||
# react-native relies on
|
||||
.*/node_modules/react-tools/src/vendor/core/ExecutionEnvironment.js
|
||||
.*/node_modules/react-tools/src/browser/eventPlugins/ResponderEventPlugin.js
|
||||
.*/node_modules/react-tools/src/browser/ui/React.js
|
||||
.*/node_modules/react-tools/src/core/ReactInstanceHandles.js
|
||||
.*/node_modules/react-tools/src/event/EventPropagators.js
|
||||
.*/node_modules/react-tools/src/React.js
|
||||
.*/node_modules/react-tools/src/renderers/shared/reconciler/ReactInstanceHandles.js
|
||||
.*/node_modules/react-tools/src/renderers/shared/event/EventPropagators.js
|
||||
.*/node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderEventPlugin.js
|
||||
.*/node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderSyntheticEvent.js
|
||||
.*/node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderTouchHistoryStore.js
|
||||
.*/node_modules/react-tools/src/shared/vendor/core/ExecutionEnvironment.js
|
||||
|
||||
# Ignore commoner tests
|
||||
.*/node_modules/commoner/test/.*
|
||||
|
|
|
@ -24,7 +24,7 @@ var {
|
|||
View,
|
||||
} = React;
|
||||
|
||||
var AnimationExperimental = require('AnimationExperimental');
|
||||
var Animated = require('Animated');
|
||||
var GameBoard = require('GameBoard');
|
||||
var TouchableBounce = require('TouchableBounce');
|
||||
|
||||
|
@ -53,58 +53,58 @@ class Board extends React.Component {
|
|||
}
|
||||
|
||||
class Tile extends React.Component {
|
||||
static _getPosition(index): number {
|
||||
return BOARD_PADDING + (index * (CELL_SIZE + CELL_MARGIN * 2) + CELL_MARGIN);
|
||||
}
|
||||
|
||||
constructor(props: {}) {
|
||||
super(props);
|
||||
|
||||
var tile = this.props.tile;
|
||||
|
||||
this.state = {
|
||||
opacity: new Animated.Value(0),
|
||||
top: new Animated.Value(Tile._getPosition(tile.toRow())),
|
||||
left: new Animated.Value(Tile._getPosition(tile.toColumn())),
|
||||
};
|
||||
}
|
||||
|
||||
calculateOffset(): {top: number; left: number; opacity: number} {
|
||||
var tile = this.props.tile;
|
||||
|
||||
var pos = (i) => {
|
||||
return BOARD_PADDING + (i * (CELL_SIZE + CELL_MARGIN * 2) + CELL_MARGIN);
|
||||
};
|
||||
|
||||
var animationPosition = (i) => {
|
||||
return pos(i) + (CELL_SIZE / 2);
|
||||
};
|
||||
|
||||
var offset = {
|
||||
top: pos(tile.toRow()),
|
||||
left: pos(tile.toColumn()),
|
||||
opacity: 1,
|
||||
top: this.state.top,
|
||||
left: this.state.left,
|
||||
opacity: this.state.opacity,
|
||||
};
|
||||
|
||||
if (tile.isNew()) {
|
||||
offset.opacity = 0;
|
||||
} else {
|
||||
var point = {
|
||||
x: animationPosition(tile.toColumn()),
|
||||
y: animationPosition(tile.toRow()),
|
||||
};
|
||||
AnimationExperimental.startAnimation({
|
||||
node: this.refs['this'],
|
||||
Animated.timing(this.state.opacity, {
|
||||
duration: 100,
|
||||
easing: 'easeInOutQuad',
|
||||
property: 'position',
|
||||
toValue: point,
|
||||
});
|
||||
toValue: 1,
|
||||
}).start();
|
||||
} else {
|
||||
Animated.parallel([
|
||||
Animated.timing(offset.top, {
|
||||
duration: 100,
|
||||
toValue: Tile._getPosition(tile.toRow()),
|
||||
}),
|
||||
Animated.timing(offset.left, {
|
||||
duration: 100,
|
||||
toValue: Tile._getPosition(tile.toColumn()),
|
||||
}),
|
||||
]).start();
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
AnimationExperimental.startAnimation({
|
||||
node: this.refs['this'],
|
||||
duration: 100,
|
||||
easing: 'easeInOutQuad',
|
||||
property: 'opacity',
|
||||
toValue: 1,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
var tile = this.props.tile;
|
||||
|
||||
var tileStyles = [
|
||||
styles.tile,
|
||||
styles['tile' + tile.value],
|
||||
this.calculateOffset()
|
||||
this.calculateOffset(),
|
||||
];
|
||||
|
||||
var textStyles = [
|
||||
|
@ -115,9 +115,9 @@ class Tile extends React.Component {
|
|||
];
|
||||
|
||||
return (
|
||||
<View ref="this" style={tileStyles}>
|
||||
<Animated.View style={tileStyles}>
|
||||
<Text style={textStyles}>{tile.value}</Text>
|
||||
</View>
|
||||
</Animated.View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -262,6 +262,7 @@ var SearchScreen = React.createClass({
|
|||
) {
|
||||
return (
|
||||
<MovieCell
|
||||
key={movie.id}
|
||||
onSelect={() => this.selectMovie(movie)}
|
||||
onHighlight={() => highlightRowFunc(sectionID, rowID)}
|
||||
onUnhighlight={() => highlightRowFunc(null, null)}
|
||||
|
@ -307,7 +308,7 @@ var NoMovies = React.createClass({
|
|||
render: function() {
|
||||
var text = '';
|
||||
if (this.props.filter) {
|
||||
text = `No results for “${this.props.filter}”`;
|
||||
text = `No results for "${this.props.filter}"`;
|
||||
} else if (!this.props.isLoading) {
|
||||
// If we're looking at the latest movies, aren't currently loading, and
|
||||
// still have no results, show a message
|
||||
|
|
|
@ -83,6 +83,26 @@ exports.examples = [{
|
|||
</View>
|
||||
);
|
||||
},
|
||||
}, {
|
||||
title: 'Status Bar Network Activity Indicator',
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<TouchableHighlight style={styles.wrapper}
|
||||
onPress={() => StatusBarIOS.setNetworkActivityIndicatorVisible(true)}>
|
||||
<View style={styles.button}>
|
||||
<Text>setNetworkActivityIndicatorVisible(true)</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
<TouchableHighlight style={styles.wrapper}
|
||||
onPress={() => StatusBarIOS.setNetworkActivityIndicatorVisible(false)}>
|
||||
<View style={styles.button}>
|
||||
<Text>setNetworkActivityIndicatorVisible(false)</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
}];
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
|
|
|
@ -39,11 +39,11 @@ var TabBarExample = React.createClass({
|
|||
};
|
||||
},
|
||||
|
||||
_renderContent: function(color: string, pageText: string) {
|
||||
_renderContent: function(color: string, pageText: string, num?: number) {
|
||||
return (
|
||||
<View style={[styles.tabContent, {backgroundColor: color}]}>
|
||||
<Text style={styles.tabText}>{pageText}</Text>
|
||||
<Text style={styles.tabText}>{this.state.presses} re-renders of the More tab</Text>
|
||||
<Text style={styles.tabText}>{num} re-renders of the {pageText}</Text>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
|
@ -51,8 +51,8 @@ var TabBarExample = React.createClass({
|
|||
render: function() {
|
||||
return (
|
||||
<TabBarIOS
|
||||
tintColor="black"
|
||||
barTintColor="#3abeff">
|
||||
tintColor="white"
|
||||
barTintColor="darkslateblue">
|
||||
<TabBarIOS.Item
|
||||
title="Blue Tab"
|
||||
selected={this.state.selectedTab === 'blueTab'}
|
||||
|
@ -73,7 +73,7 @@ var TabBarExample = React.createClass({
|
|||
notifCount: this.state.notifCount + 1,
|
||||
});
|
||||
}}>
|
||||
{this._renderContent('#783E33', 'Red Tab')}
|
||||
{this._renderContent('#783E33', 'Red Tab', this.state.notifCount)}
|
||||
</TabBarIOS.Item>
|
||||
<TabBarIOS.Item
|
||||
systemIcon="more"
|
||||
|
@ -84,7 +84,7 @@ var TabBarExample = React.createClass({
|
|||
presses: this.state.presses + 1
|
||||
});
|
||||
}}>
|
||||
{this._renderContent('#21551C', 'Green Tab')}
|
||||
{this._renderContent('#21551C', 'Green Tab', this.state.presses)}
|
||||
</TabBarIOS.Item>
|
||||
</TabBarIOS>
|
||||
);
|
||||
|
|
|
@ -269,7 +269,7 @@ exports.examples = [
|
|||
right right right right right right right right right right right right right
|
||||
</Text>
|
||||
<Text style={{textAlign: 'justify'}}>
|
||||
justify: this text component's contents are laid out with "textAlign: justify"
|
||||
justify: this text component{"'"}s contents are laid out with "textAlign: justify"
|
||||
and as you can see all of the lines except the last one span the
|
||||
available width of the parent container.
|
||||
</Text>
|
||||
|
@ -369,6 +369,15 @@ exports.examples = [
|
|||
</View>
|
||||
);
|
||||
},
|
||||
}, {
|
||||
title: 'Text highlighting (tap the link to see highlight)',
|
||||
render: function() {
|
||||
return (
|
||||
<View>
|
||||
<Text>Lorem ipsum dolor sit amet, <Text suppressHighlighting={false} style={{backgroundColor: 'white', textDecorationLine: 'underline', color: 'blue'}} onPress={() => null}>consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud</Text> exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</Text>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
}];
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
|
|
|
@ -411,7 +411,7 @@ exports.examples = [
|
|||
style={styles.multiline}
|
||||
/>
|
||||
<TextInput
|
||||
placeholder="mutliline text input with font styles and placeholder"
|
||||
placeholder="multiline text input with font styles and placeholder"
|
||||
multiline={true}
|
||||
clearTextOnFocus={true}
|
||||
autoCorrect={true}
|
||||
|
@ -421,7 +421,7 @@ exports.examples = [
|
|||
style={[styles.multiline, styles.multilineWithFontStyles]}
|
||||
/>
|
||||
<TextInput
|
||||
placeholder="uneditable mutliline text input"
|
||||
placeholder="uneditable multiline text input"
|
||||
editable={false}
|
||||
multiline={true}
|
||||
style={styles.multiline}
|
||||
|
|
|
@ -1034,9 +1034,11 @@
|
|||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_STRICT_SELECTOR_MATCH = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
|
@ -1089,9 +1091,11 @@
|
|||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_STRICT_SELECTOR_MATCH = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
@ -121,23 +121,30 @@ class UIExplorerList extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.props.navigator.navigationContext.addListener('didfocus', function(event) {
|
||||
if (event.data.route.title === 'UIExplorer') {
|
||||
Settings.set({visibleExample: null});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
var visibleExampleTitle = Settings.get('visibleExample');
|
||||
if (visibleExampleTitle) {
|
||||
var predicate = (example) => example.title === visibleExampleTitle;
|
||||
var foundExample = APIS.find(predicate) || COMPONENTS.find(predicate);
|
||||
if (foundExample) {
|
||||
setTimeout(() => this._openExample(foundExample), 100);
|
||||
var wasUIExplorer = false;
|
||||
var didOpenExample = false;
|
||||
|
||||
this.props.navigator.navigationContext.addListener('didfocus', (event) => {
|
||||
var isUIExplorer = event.data.route.title === 'UIExplorer';
|
||||
|
||||
if (!didOpenExample && isUIExplorer) {
|
||||
didOpenExample = true;
|
||||
|
||||
var visibleExampleTitle = Settings.get('visibleExample');
|
||||
if (visibleExampleTitle) {
|
||||
var predicate = (example) => example.title === visibleExampleTitle;
|
||||
var foundExample = APIS.find(predicate) || COMPONENTS.find(predicate);
|
||||
if (foundExample) {
|
||||
setTimeout(() => this._openExample(foundExample), 100);
|
||||
}
|
||||
} else if (!wasUIExplorer && isUIExplorer) {
|
||||
Settings.set({visibleExample: null});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wasUIExplorer = isUIExplorer;
|
||||
});
|
||||
}
|
||||
|
||||
renderAdditionalView(renderRow: Function, renderTextInput: Function): React.Component {
|
||||
|
|
|
@ -166,15 +166,6 @@ class UIExplorerList extends React.Component {
|
|||
|
||||
componentDidMount() {
|
||||
this._search(this.state.searchText);
|
||||
|
||||
var visibleExampleTitle = Settings.get('visibleExample');
|
||||
if (visibleExampleTitle) {
|
||||
var predicate = (example) => example.title === visibleExampleTitle;
|
||||
var foundExample = APIS.find(predicate) || COMPONENTS.find(predicate);
|
||||
if (foundExample) {
|
||||
setTimeout(() => this._openExample(foundExample), 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
@ -54,8 +54,9 @@ var createExamplePage = function(title: ?string, exampleModule: ExampleModule)
|
|||
};
|
||||
var result = example.render(null);
|
||||
if (result) {
|
||||
renderedComponent = result;
|
||||
result.props.navigator = this.props.navigator;
|
||||
renderedComponent = React.cloneElement(result, {
|
||||
navigator: this.props.navigator,
|
||||
});
|
||||
}
|
||||
(React: Object).render = originalRender;
|
||||
(React: Object).renderComponent = originalRenderComponent;
|
||||
|
|
|
@ -151,6 +151,7 @@
|
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
@ -190,6 +191,7 @@
|
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
|
|
@ -151,6 +151,7 @@
|
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
@ -195,6 +196,7 @@
|
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
|
|
@ -1,99 +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.
|
||||
*
|
||||
* @providesModule AnimationExperimental
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var RCTAnimationManager = require('NativeModules').AnimationExperimentalManager;
|
||||
if (!RCTAnimationManager) {
|
||||
// AnimationExperimental isn't available internally - this is a temporary
|
||||
// workaround to enable its availability to be determined at runtime.
|
||||
// For Flow let's pretend like we always export AnimationExperimental
|
||||
// so all our users don't need to do null checks
|
||||
module.exports = null;
|
||||
} else {
|
||||
|
||||
var React = require('React');
|
||||
var AnimationUtils = require('AnimationUtils');
|
||||
|
||||
type EasingFunction = (t: number) => number;
|
||||
|
||||
var Properties = {
|
||||
opacity: true,
|
||||
position: true,
|
||||
positionX: true,
|
||||
positionY: true,
|
||||
rotation: true,
|
||||
scaleXY: true,
|
||||
};
|
||||
|
||||
type ValueType = number | Array<number> | {[key: string]: number};
|
||||
|
||||
/**
|
||||
* This is an experimental module that is under development, incomplete,
|
||||
* potentially buggy, not used in any production apps, and will probably change
|
||||
* in non-backward compatible ways.
|
||||
*
|
||||
* Use at your own risk.
|
||||
*/
|
||||
var AnimationExperimental = {
|
||||
startAnimation: function(
|
||||
anim: {
|
||||
node: any;
|
||||
duration: number;
|
||||
easing: ($Enum<typeof AnimationUtils.Defaults> | EasingFunction);
|
||||
property: $Enum<typeof Properties>;
|
||||
toValue: ValueType;
|
||||
fromValue?: ValueType;
|
||||
delay?: number;
|
||||
},
|
||||
callback?: ?(finished: bool) => void
|
||||
): number {
|
||||
var nodeHandle = React.findNodeHandle(anim.node);
|
||||
var easingSample = AnimationUtils.evaluateEasingFunction(
|
||||
anim.duration,
|
||||
anim.easing
|
||||
);
|
||||
var tag: number = AnimationUtils.allocateTag();
|
||||
var props = {};
|
||||
props[anim.property] = {to: anim.toValue};
|
||||
RCTAnimationManager.startAnimation(
|
||||
nodeHandle,
|
||||
tag,
|
||||
anim.duration,
|
||||
anim.delay,
|
||||
easingSample,
|
||||
props,
|
||||
callback
|
||||
);
|
||||
return tag;
|
||||
},
|
||||
|
||||
stopAnimation: function(tag: number) {
|
||||
RCTAnimationManager.stopAnimation(tag);
|
||||
},
|
||||
};
|
||||
|
||||
if (__DEV__) {
|
||||
if (RCTAnimationManager && RCTAnimationManager.Properties) {
|
||||
var a = Object.keys(Properties);
|
||||
var b = RCTAnimationManager.Properties;
|
||||
var diff = a.filter((i) => b.indexOf(i) < 0).concat(
|
||||
b.filter((i) => a.indexOf(i) < 0)
|
||||
);
|
||||
if (diff.length > 0) {
|
||||
throw new Error('JS animation properties don\'t match native properties.' +
|
||||
JSON.stringify(diff, null, ' '));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AnimationExperimental;
|
||||
|
||||
}
|
|
@ -1,244 +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.
|
||||
*
|
||||
* The easing functions come from the the jQuery UI project.
|
||||
* See http://api.jqueryui.com/easings/
|
||||
* Copyright jQuery Foundation and other contributors, https://jquery.org/
|
||||
* Copyright (c) 2008 George McGinley Smith
|
||||
* Copyright (c) 2001 Robert Penner
|
||||
*
|
||||
* @providesModule AnimationUtils
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
type EasingFunction = (t: number) => number;
|
||||
|
||||
var defaults = {
|
||||
linear: function(t: number): number {
|
||||
return t;
|
||||
},
|
||||
easeInQuad: function(t: number): number {
|
||||
return t * t;
|
||||
},
|
||||
easeOutQuad: function(t: number): number {
|
||||
return -t * (t - 2);
|
||||
},
|
||||
easeInOutQuad: function(t: number): number {
|
||||
t = t * 2;
|
||||
if (t < 1) {
|
||||
return 0.5 * t * t;
|
||||
}
|
||||
return -((t - 1) * (t - 3) - 1) / 2;
|
||||
},
|
||||
easeInCubic: function(t: number): number {
|
||||
return t * t * t;
|
||||
},
|
||||
easeOutCubic: function(t: number): number {
|
||||
t -= 1;
|
||||
return t * t * t + 1;
|
||||
},
|
||||
easeInOutCubic: function(t: number): number {
|
||||
t *= 2;
|
||||
if (t < 1) {
|
||||
return 0.5 * t * t * t;
|
||||
}
|
||||
t -= 2;
|
||||
return (t * t * t + 2) / 2;
|
||||
},
|
||||
easeInQuart: function(t: number): number {
|
||||
return t * t * t * t;
|
||||
},
|
||||
easeOutQuart: function(t: number): number {
|
||||
t -= 1;
|
||||
return -(t * t * t * t - 1);
|
||||
},
|
||||
easeInOutQuart: function(t: number): number {
|
||||
t *= 2;
|
||||
if (t < 1) {
|
||||
return 0.5 * t * t * t * t;
|
||||
}
|
||||
t -= 2;
|
||||
return -(t * t * t * t - 2) / 2;
|
||||
},
|
||||
easeInQuint: function(t: number): number {
|
||||
return t * t * t * t * t;
|
||||
},
|
||||
easeOutQuint: function(t: number): number {
|
||||
t -= 1;
|
||||
return t * t * t * t * t + 1;
|
||||
},
|
||||
easeInOutQuint: function(t: number): number {
|
||||
t *= 2;
|
||||
if (t < 1) {
|
||||
return (t * t * t * t * t) / 2;
|
||||
}
|
||||
t -= 2;
|
||||
return (t * t * t * t * t + 2) / 2;
|
||||
},
|
||||
easeInSine: function(t: number): number {
|
||||
return -Math.cos(t * (Math.PI / 2)) + 1;
|
||||
},
|
||||
easeOutSine: function(t: number): number {
|
||||
return Math.sin(t * (Math.PI / 2));
|
||||
},
|
||||
easeInOutSine: function(t: number): number {
|
||||
return -(Math.cos(Math.PI * t) - 1) / 2;
|
||||
},
|
||||
easeInExpo: function(t: number): number {
|
||||
return (t === 0) ? 0 : Math.pow(2, 10 * (t - 1));
|
||||
},
|
||||
easeOutExpo: function(t: number): number {
|
||||
return (t === 1) ? 1 : (-Math.pow(2, -10 * t) + 1);
|
||||
},
|
||||
easeInOutExpo: function(t: number): number {
|
||||
if (t === 0) {
|
||||
return 0;
|
||||
}
|
||||
if (t === 1) {
|
||||
return 1;
|
||||
}
|
||||
t *= 2;
|
||||
if (t < 1) {
|
||||
return 0.5 * Math.pow(2, 10 * (t - 1));
|
||||
}
|
||||
return (-Math.pow(2, -10 * (t - 1)) + 2) / 2;
|
||||
},
|
||||
easeInCirc: function(t: number): number {
|
||||
return -(Math.sqrt(1 - t * t) - 1);
|
||||
},
|
||||
easeOutCirc: function(t: number): number {
|
||||
t -= 1;
|
||||
return Math.sqrt(1 - t * t);
|
||||
},
|
||||
easeInOutCirc: function(t: number): number {
|
||||
t *= 2;
|
||||
if (t < 1) {
|
||||
return -(Math.sqrt(1 - t * t) - 1) / 2;
|
||||
}
|
||||
t -= 2;
|
||||
return (Math.sqrt(1 - t * t) + 1) / 2;
|
||||
},
|
||||
easeInElastic: function(t: number): number {
|
||||
var s = 1.70158;
|
||||
var p = 0.3;
|
||||
if (t === 0) {
|
||||
return 0;
|
||||
}
|
||||
if (t === 1) {
|
||||
return 1;
|
||||
}
|
||||
var s = p / (2 * Math.PI) * Math.asin(1);
|
||||
t -= 1;
|
||||
return -(Math.pow(2, 10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));
|
||||
},
|
||||
easeOutElastic: function(t: number): number {
|
||||
var s = 1.70158;
|
||||
var p = 0.3;
|
||||
if (t === 0) {
|
||||
return 0;
|
||||
}
|
||||
if (t === 1) {
|
||||
return 1;
|
||||
}
|
||||
var s = p / (2 * Math.PI) * Math.asin(1);
|
||||
return Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1;
|
||||
},
|
||||
easeInOutElastic: function(t: number): number {
|
||||
var s = 1.70158;
|
||||
var p = 0.3 * 1.5;
|
||||
if (t === 0) {
|
||||
return 0;
|
||||
}
|
||||
t *= 2;
|
||||
if (t === 2) {
|
||||
return 1;
|
||||
}
|
||||
var s = p / (2 * Math.PI) * Math.asin(1);
|
||||
if (t < 1) {
|
||||
t -= 1;
|
||||
return -(Math.pow(2, 10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p)) / 2;
|
||||
}
|
||||
t -= 1;
|
||||
return Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) / 2 + 1;
|
||||
},
|
||||
easeInBack: function(t: number): number {
|
||||
var s = 1.70158;
|
||||
return t * t * ((s + 1) * t - s);
|
||||
},
|
||||
easeOutBack: function(t: number): number {
|
||||
var s = 1.70158;
|
||||
t -= 1;
|
||||
return (t * t * ((s + 1) * t + s) + 1);
|
||||
},
|
||||
easeInOutBack: function(t: number): number {
|
||||
var s = 1.70158 * 1.525;
|
||||
t *= 2;
|
||||
if (t < 1) {
|
||||
return (t * t * ((s + 1) * t - s)) / 2;
|
||||
}
|
||||
t -= 2;
|
||||
return (t * t * ((s + 1) * t + s) + 2) / 2;
|
||||
},
|
||||
easeInBounce: function(t: number): number {
|
||||
return 1 - this.easeOutBounce(1 - t);
|
||||
},
|
||||
easeOutBounce: function(t: number): number {
|
||||
if (t < (1 / 2.75)) {
|
||||
return 7.5625 * t * t;
|
||||
} else if (t < (2 / 2.75)) {
|
||||
t -= 1.5 / 2.75;
|
||||
return 7.5625 * t * t + 0.75;
|
||||
} else if (t < (2.5 / 2.75)) {
|
||||
t -= 2.25 / 2.75;
|
||||
return 7.5625 * t * t + 0.9375;
|
||||
} else {
|
||||
t -= 2.625 / 2.75;
|
||||
return 7.5625 * t * t + 0.984375;
|
||||
}
|
||||
},
|
||||
easeInOutBounce: function(t: number): number {
|
||||
if (t < 0.5) {
|
||||
return this.easeInBounce(t * 2) / 2;
|
||||
}
|
||||
return this.easeOutBounce(t * 2 - 1) / 2 + 0.5;
|
||||
},
|
||||
};
|
||||
|
||||
var ticksPerSecond = 60;
|
||||
var lastUsedTag = 0;
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* Returns a new unique animation tag.
|
||||
*/
|
||||
allocateTag: function(): number {
|
||||
return ++lastUsedTag;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the values of the easing function at discrete ticks (60 per second).
|
||||
*/
|
||||
evaluateEasingFunction: function(duration: number, easing: string | EasingFunction): Array<number> {
|
||||
if (typeof easing === 'string') {
|
||||
easing = defaults[easing] || defaults.easeOutQuad;
|
||||
}
|
||||
|
||||
var tickCount = Math.round(duration * ticksPerSecond / 1000);
|
||||
var samples = [];
|
||||
if (tickCount > 0) {
|
||||
for (var i = 0; i <= tickCount; i++) {
|
||||
samples.push(easing.call(defaults, i / tickCount));
|
||||
}
|
||||
}
|
||||
|
||||
return samples;
|
||||
},
|
||||
|
||||
Defaults: defaults,
|
||||
};
|
|
@ -1,250 +0,0 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
13BE3DEE1AC21097009241FE /* RCTAnimationExperimentalManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13BE3DED1AC21097009241FE /* RCTAnimationExperimentalManager.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
58B511D91A9E6C8500147676 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "include/$(PRODUCT_NAME)";
|
||||
dstSubfolderSpec = 16;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
134814201AA4EA6300B7C361 /* libRCTAnimationExperimental.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTAnimationExperimental.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
13BE3DEC1AC21097009241FE /* RCTAnimationExperimentalManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAnimationExperimentalManager.h; sourceTree = "<group>"; };
|
||||
13BE3DED1AC21097009241FE /* RCTAnimationExperimentalManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTAnimationExperimentalManager.m; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
58B511D81A9E6C8500147676 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
134814211AA4EA7D00B7C361 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
134814201AA4EA6300B7C361 /* libRCTAnimationExperimental.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
58B511D21A9E6C8500147676 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13BE3DEC1AC21097009241FE /* RCTAnimationExperimentalManager.h */,
|
||||
13BE3DED1AC21097009241FE /* RCTAnimationExperimentalManager.m */,
|
||||
134814211AA4EA7D00B7C361 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
58B511DA1A9E6C8500147676 /* RCTAnimationExperimental */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTAnimationExperimental" */;
|
||||
buildPhases = (
|
||||
58B511D71A9E6C8500147676 /* Sources */,
|
||||
58B511D81A9E6C8500147676 /* Frameworks */,
|
||||
58B511D91A9E6C8500147676 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = RCTAnimationExperimental;
|
||||
productName = RCTDataManager;
|
||||
productReference = 134814201AA4EA6300B7C361 /* libRCTAnimationExperimental.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
58B511D31A9E6C8500147676 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0610;
|
||||
ORGANIZATIONNAME = Facebook;
|
||||
TargetAttributes = {
|
||||
58B511DA1A9E6C8500147676 = {
|
||||
CreatedOnToolsVersion = 6.1.1;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTAnimationExperimental" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = 58B511D21A9E6C8500147676;
|
||||
productRefGroup = 58B511D21A9E6C8500147676;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
58B511DA1A9E6C8500147676 /* RCTAnimationExperimental */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
58B511D71A9E6C8500147676 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13BE3DEE1AC21097009241FE /* RCTAnimationExperimentalManager.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
58B511ED1A9E6C8500147676 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
58B511EE1A9E6C8500147676 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
58B511F01A9E6C8500147676 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = RCTAnimationExperimental;
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
58B511F11A9E6C8500147676 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = RCTAnimationExperimental;
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTAnimationExperimental" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
58B511ED1A9E6C8500147676 /* Debug */,
|
||||
58B511EE1A9E6C8500147676 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTAnimationExperimental" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
58B511F01A9E6C8500147676 /* Debug */,
|
||||
58B511F11A9E6C8500147676 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 58B511D31A9E6C8500147676 /* Project object */;
|
||||
}
|
|
@ -1,299 +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.
|
||||
*/
|
||||
|
||||
#import "RCTAnimationExperimentalManager.h"
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "RCTSparseArray.h"
|
||||
#import "RCTUIManager.h"
|
||||
#import "RCTUtils.h"
|
||||
|
||||
#if CGFLOAT_IS_DOUBLE
|
||||
#define CG_APPEND(PREFIX, SUFFIX_F, SUFFIX_D) PREFIX##SUFFIX_D
|
||||
#else
|
||||
#define CG_APPEND(PREFIX, SUFFIX_F, SUFFIX_D) PREFIX##SUFFIX_F
|
||||
#endif
|
||||
|
||||
@implementation RCTAnimationExperimentalManager
|
||||
{
|
||||
RCTSparseArray *_animationRegistry; // Main thread only; animation tag -> view tag
|
||||
RCTSparseArray *_callbackRegistry; // Main thread only; animation tag -> callback
|
||||
NSDictionary *_keypathMapping;
|
||||
}
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
@synthesize bridge = _bridge;
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_animationRegistry = [[RCTSparseArray alloc] init];
|
||||
_callbackRegistry = [[RCTSparseArray alloc] init];
|
||||
_keypathMapping = @{
|
||||
@"opacity": @{
|
||||
@"keypath": @"opacity",
|
||||
@"type": @"NSNumber",
|
||||
},
|
||||
@"position": @{
|
||||
@"keypath": @"position",
|
||||
@"type": @"CGPoint",
|
||||
},
|
||||
@"positionX": @{
|
||||
@"keypath": @"position.x",
|
||||
@"type": @"NSNumber",
|
||||
},
|
||||
@"positionY": @{
|
||||
@"keypath": @"position.y",
|
||||
@"type": @"NSNumber",
|
||||
},
|
||||
@"rotation": @{
|
||||
@"keypath": @"transform.rotation.z",
|
||||
@"type": @"NSNumber",
|
||||
},
|
||||
@"scaleXY": @{
|
||||
@"keypath": @"transform.scale",
|
||||
@"type": @"CGPoint",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (dispatch_queue_t)methodQueue
|
||||
{
|
||||
return _bridge.uiManager.methodQueue;
|
||||
}
|
||||
|
||||
- (id (^)(CGFloat))interpolateFrom:(CGFloat[])fromArray to:(CGFloat[])toArray count:(NSUInteger)count typeName:(const char *)typeName
|
||||
{
|
||||
if (count == 1) {
|
||||
CGFloat from = *fromArray, to = *toArray, delta = to - from;
|
||||
return ^(CGFloat t) {
|
||||
return @(from + t * delta);
|
||||
};
|
||||
}
|
||||
|
||||
CG_APPEND(vDSP_vsub,,D)(fromArray, 1, toArray, 1, toArray, 1, count);
|
||||
|
||||
const size_t size = count * sizeof(CGFloat);
|
||||
NSData *deltaData = [NSData dataWithBytes:toArray length:size];
|
||||
NSData *fromData = [NSData dataWithBytes:fromArray length:size];
|
||||
|
||||
return ^(CGFloat t) {
|
||||
const CGFloat *delta = deltaData.bytes;
|
||||
const CGFloat *_fromArray = fromData.bytes;
|
||||
|
||||
CGFloat value[count];
|
||||
CG_APPEND(vDSP_vma,,D)(delta, 1, &t, 0, _fromArray, 1, value, 1, count);
|
||||
return [NSValue valueWithBytes:value objCType:typeName];
|
||||
};
|
||||
}
|
||||
|
||||
static void RCTInvalidAnimationProp(RCTSparseArray *callbacks, NSNumber *tag, NSString *key, id value)
|
||||
{
|
||||
RCTResponseSenderBlock callback = callbacks[tag];
|
||||
RCTLogError(@"Invalid animation property `%@ = %@`", key, value);
|
||||
if (callback) {
|
||||
callback(@[@NO]);
|
||||
callbacks[tag] = nil;
|
||||
}
|
||||
[CATransaction commit];
|
||||
return;
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(startAnimation:(NSNumber *)reactTag
|
||||
animationTag:(NSNumber *)animationTag
|
||||
duration:(NSTimeInterval)duration
|
||||
delay:(NSTimeInterval)delay
|
||||
easingSample:(NSNumberArray *)easingSample
|
||||
properties:(NSDictionary *)properties
|
||||
callback:(RCTResponseSenderBlock)callback)
|
||||
{
|
||||
__weak RCTAnimationExperimentalManager *weakSelf = self;
|
||||
[_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
||||
RCTAnimationExperimentalManager *strongSelf = weakSelf;
|
||||
|
||||
UIView *view = viewRegistry[reactTag];
|
||||
if (!view) {
|
||||
RCTLogWarn(@"React tag #%@ is not registered with the view registry", reactTag);
|
||||
return;
|
||||
}
|
||||
__block BOOL completionBlockSet = NO;
|
||||
[CATransaction begin];
|
||||
for (NSString *prop in properties) {
|
||||
NSString *keypath = _keypathMapping[prop][@"keypath"];
|
||||
id obj = properties[prop][@"to"];
|
||||
if (!keypath) {
|
||||
return RCTInvalidAnimationProp(strongSelf->_callbackRegistry, animationTag, keypath, obj);
|
||||
}
|
||||
NSValue *toValue = nil;
|
||||
if ([keypath isEqualToString:@"transform.scale"]) {
|
||||
CGPoint point = [RCTConvert CGPoint:obj];
|
||||
if (point.x != point.y) {
|
||||
return RCTInvalidAnimationProp(strongSelf->_callbackRegistry, animationTag, keypath, obj);
|
||||
}
|
||||
toValue = @(point.x);
|
||||
} else if ([obj respondsToSelector:@selector(count)]) {
|
||||
switch ([obj count]) {
|
||||
case 2:
|
||||
if (![obj respondsToSelector:@selector(objectForKeyedSubscript:)] || obj[@"x"]) {
|
||||
toValue = [NSValue valueWithCGPoint:[RCTConvert CGPoint:obj]];
|
||||
} else {
|
||||
toValue = [NSValue valueWithCGSize:[RCTConvert CGSize:obj]];
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
toValue = [NSValue valueWithCGRect:[RCTConvert CGRect:obj]];
|
||||
break;
|
||||
case 16:
|
||||
toValue = [NSValue valueWithCGAffineTransform:[RCTConvert CGAffineTransform:obj]];
|
||||
break;
|
||||
default:
|
||||
return RCTInvalidAnimationProp(strongSelf->_callbackRegistry, animationTag, keypath, obj);
|
||||
}
|
||||
} else if (![obj respondsToSelector:@selector(objCType)]) {
|
||||
return RCTInvalidAnimationProp(strongSelf->_callbackRegistry, animationTag, keypath, obj);
|
||||
}
|
||||
if (!toValue) {
|
||||
toValue = obj;
|
||||
}
|
||||
const char *typeName = toValue.objCType;
|
||||
|
||||
size_t count;
|
||||
switch (typeName[0]) {
|
||||
case 'i':
|
||||
case 'I':
|
||||
case 's':
|
||||
case 'S':
|
||||
case 'l':
|
||||
case 'L':
|
||||
case 'q':
|
||||
case 'Q':
|
||||
count = 1;
|
||||
break;
|
||||
|
||||
default: {
|
||||
NSUInteger size;
|
||||
NSGetSizeAndAlignment(typeName, &size, NULL);
|
||||
count = size / sizeof(CGFloat);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CGFloat toFields[count];
|
||||
|
||||
switch (typeName[0]) {
|
||||
#define CASE(encoding, type) \
|
||||
case encoding: { \
|
||||
type value; \
|
||||
[toValue getValue:&value]; \
|
||||
toFields[0] = value; \
|
||||
break; \
|
||||
}
|
||||
|
||||
CASE('i', int)
|
||||
CASE('I', unsigned int)
|
||||
CASE('s', short)
|
||||
CASE('S', unsigned short)
|
||||
CASE('l', long)
|
||||
CASE('L', unsigned long)
|
||||
CASE('q', long long)
|
||||
CASE('Q', unsigned long long)
|
||||
|
||||
#undef CASE
|
||||
|
||||
default:
|
||||
[toValue getValue:toFields];
|
||||
break;
|
||||
}
|
||||
|
||||
NSValue *fromValue = [view.layer.presentationLayer valueForKeyPath:keypath];
|
||||
#if !CGFLOAT_IS_DOUBLE
|
||||
if ([fromValue isKindOfClass:[NSNumber class]]) {
|
||||
fromValue = [NSNumber numberWithFloat:[(NSNumber *)fromValue doubleValue]];
|
||||
}
|
||||
#endif
|
||||
CGFloat fromFields[count];
|
||||
[fromValue getValue:fromFields];
|
||||
|
||||
id (^interpolationBlock)(CGFloat t) = [strongSelf interpolateFrom:fromFields to:toFields count:count typeName:typeName];
|
||||
|
||||
NSMutableArray *sampledValues = [NSMutableArray arrayWithCapacity:easingSample.count];
|
||||
for (NSNumber *sample in easingSample) {
|
||||
CGFloat t = sample.CG_APPEND(, floatValue, doubleValue);
|
||||
[sampledValues addObject:interpolationBlock(t)];
|
||||
}
|
||||
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:keypath];
|
||||
animation.beginTime = CACurrentMediaTime() + delay;
|
||||
animation.duration = duration;
|
||||
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
|
||||
animation.values = sampledValues;
|
||||
@try {
|
||||
[view.layer setValue:toValue forKey:keypath];
|
||||
NSString *animationKey = [@"RCT" stringByAppendingString:RCTJSONStringify(@{@"tag": animationTag, @"key": keypath}, nil)];
|
||||
if (!completionBlockSet) {
|
||||
strongSelf->_callbackRegistry[animationTag] = callback;
|
||||
[CATransaction setCompletionBlock:^{
|
||||
RCTResponseSenderBlock cb = strongSelf->_callbackRegistry[animationTag];
|
||||
if (cb) {
|
||||
cb(@[@YES]);
|
||||
strongSelf->_callbackRegistry[animationTag] = nil;
|
||||
}
|
||||
}];
|
||||
completionBlockSet = YES;
|
||||
}
|
||||
[view.layer addAnimation:animation forKey:animationKey];
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
return RCTInvalidAnimationProp(strongSelf->_callbackRegistry, animationTag, keypath, toValue);
|
||||
}
|
||||
}
|
||||
[CATransaction commit];
|
||||
strongSelf->_animationRegistry[animationTag] = reactTag;
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(stopAnimation:(NSNumber *)animationTag)
|
||||
{
|
||||
__weak RCTAnimationExperimentalManager *weakSelf = self;
|
||||
[_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
||||
RCTAnimationExperimentalManager *strongSelf = weakSelf;
|
||||
|
||||
NSNumber *reactTag = strongSelf->_animationRegistry[animationTag];
|
||||
if (!reactTag) {
|
||||
return;
|
||||
}
|
||||
|
||||
UIView *view = viewRegistry[reactTag];
|
||||
for (NSString *animationKey in view.layer.animationKeys) {
|
||||
if ([animationKey hasPrefix:@"RCT{"]) {
|
||||
NSDictionary *data = RCTJSONParse([animationKey substringFromIndex:3], nil);
|
||||
if (animationTag.integerValue == [data[@"tag"] integerValue]) {
|
||||
[view.layer removeAnimationForKey:animationKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
RCTResponseSenderBlock cb = strongSelf->_callbackRegistry[animationTag];
|
||||
if (cb) {
|
||||
cb(@[@NO]);
|
||||
strongSelf->_callbackRegistry[animationTag] = nil;
|
||||
}
|
||||
strongSelf->_animationRegistry[animationTag] = nil;
|
||||
}];
|
||||
}
|
||||
|
||||
- (NSDictionary *)constantsToExport
|
||||
{
|
||||
return @{@"Properties": [_keypathMapping allKeys] };
|
||||
}
|
||||
|
||||
@end
|
|
@ -18,7 +18,6 @@ var StyleSheet = require('StyleSheet');
|
|||
var View = require('View');
|
||||
|
||||
var requireNativeComponent = require('requireNativeComponent');
|
||||
var verifyPropTypes = require('verifyPropTypes');
|
||||
|
||||
var GRAY = '#999999';
|
||||
|
||||
|
@ -99,15 +98,8 @@ var styles = StyleSheet.create({
|
|||
|
||||
var RCTActivityIndicatorView = requireNativeComponent(
|
||||
'RCTActivityIndicatorView',
|
||||
null
|
||||
ActivityIndicatorIOS,
|
||||
{nativeOnly: {activityIndicatorViewStyle: true}},
|
||||
);
|
||||
if (__DEV__) {
|
||||
var nativeOnlyProps = {activityIndicatorViewStyle: true};
|
||||
verifyPropTypes(
|
||||
ActivityIndicatorIOS,
|
||||
RCTActivityIndicatorView.viewConfig,
|
||||
nativeOnlyProps
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = ActivityIndicatorIOS;
|
||||
|
|
|
@ -15,17 +15,14 @@ var EventEmitter = require('EventEmitter');
|
|||
var Image = require('Image');
|
||||
var NavigationContext = require('NavigationContext');
|
||||
var React = require('React');
|
||||
var ReactNativeViewAttributes = require('ReactNativeViewAttributes');
|
||||
var RCTNavigatorManager = require('NativeModules').NavigatorManager;
|
||||
var StyleSheet = require('StyleSheet');
|
||||
var StaticContainer = require('StaticContainer.react');
|
||||
var View = require('View');
|
||||
|
||||
var createReactNativeComponentClass =
|
||||
require('createReactNativeComponentClass');
|
||||
var requireNativeComponent = require('requireNativeComponent');
|
||||
var invariant = require('invariant');
|
||||
var logError = require('logError');
|
||||
var merge = require('merge');
|
||||
|
||||
var TRANSITIONER_REF = 'transitionerRef';
|
||||
|
||||
|
@ -36,37 +33,6 @@ function getuid() {
|
|||
return __uid++;
|
||||
}
|
||||
|
||||
var RCTNavigator = createReactNativeComponentClass({
|
||||
validAttributes: merge(ReactNativeViewAttributes.UIView, {
|
||||
requestedTopOfStack: true
|
||||
}),
|
||||
uiViewClassName: 'RCTNavigator',
|
||||
});
|
||||
|
||||
var RCTNavigatorItem = createReactNativeComponentClass({
|
||||
validAttributes: {
|
||||
// TODO: Remove or fix the attributes that are not fully functional.
|
||||
// NavigatorIOS does not use them all, because some are problematic
|
||||
title: true,
|
||||
barTintColor: true,
|
||||
leftButtonIcon: true,
|
||||
leftButtonTitle: true,
|
||||
onNavLeftButtonTap: true,
|
||||
rightButtonIcon: true,
|
||||
rightButtonTitle: true,
|
||||
onNavRightButtonTap: true,
|
||||
backButtonIcon: true,
|
||||
backButtonTitle: true,
|
||||
tintColor: true,
|
||||
translucent: true,
|
||||
navigationBarHidden: true,
|
||||
shadowHidden: true,
|
||||
titleTextColor: true,
|
||||
style: true,
|
||||
},
|
||||
uiViewClassName: 'RCTNavItem',
|
||||
});
|
||||
|
||||
var NavigatorTransitionerIOS = React.createClass({
|
||||
requestSchedulingNavigation: function(cb) {
|
||||
RCTNavigatorManager.requestSchedulingJavaScriptNavigation(
|
||||
|
@ -711,4 +677,7 @@ var styles = StyleSheet.create({
|
|||
},
|
||||
});
|
||||
|
||||
var RCTNavigator = requireNativeComponent('RCTNavigator');
|
||||
var RCTNavigatorItem = requireNativeComponent('RCTNavItem');
|
||||
|
||||
module.exports = NavigatorIOS;
|
||||
|
|
|
@ -19,7 +19,6 @@ var React = require('React');
|
|||
var StyleSheet = require('StyleSheet');
|
||||
|
||||
var requireNativeComponent = require('requireNativeComponent');
|
||||
var verifyPropTypes = require('verifyPropTypes');
|
||||
|
||||
/**
|
||||
* Use `ProgressViewIOS` to render a UIProgressView on iOS.
|
||||
|
|
|
@ -12,13 +12,13 @@
|
|||
'use strict';
|
||||
|
||||
var NativeModules = require('NativeModules');
|
||||
var Platform = require('Platform');
|
||||
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
|
||||
var React = require('React');
|
||||
var Subscribable = require('Subscribable');
|
||||
var TextInputState = require('TextInputState');
|
||||
|
||||
var RCTUIManager = NativeModules.UIManager;
|
||||
var RCTUIManagerDeprecated = NativeModules.UIManager;
|
||||
var RCTScrollViewConsts = RCTUIManager.RCTScrollView.Constants;
|
||||
|
||||
var warning = require('warning');
|
||||
|
@ -351,7 +351,19 @@ var ScrollResponderMixin = {
|
|||
* can also be used to quickly scroll to any element we want to focus
|
||||
*/
|
||||
scrollResponderScrollTo: function(offsetX: number, offsetY: number) {
|
||||
RCTUIManagerDeprecated.scrollTo(React.findNodeHandle(this), offsetX, offsetY);
|
||||
if (Platform.OS === 'android') {
|
||||
RCTUIManager.dispatchViewManagerCommand(
|
||||
React.findNodeHandle(this),
|
||||
RCTUIManager.RCTScrollView.Commands.scrollTo,
|
||||
[offsetX, offsetY],
|
||||
);
|
||||
} else {
|
||||
RCTUIManager.scrollTo(
|
||||
React.findNodeHandle(this),
|
||||
offsetX,
|
||||
offsetY
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -359,7 +371,7 @@ var ScrollResponderMixin = {
|
|||
* @param {object} rect Should have shape {x, y, width, height}
|
||||
*/
|
||||
scrollResponderZoomTo: function(rect: { x: number; y: number; width: number; height: number; }) {
|
||||
RCTUIManagerDeprecated.zoomToRect(React.findNodeHandle(this), rect);
|
||||
RCTUIManager.zoomToRect(React.findNodeHandle(this), rect);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -377,7 +389,7 @@ var ScrollResponderMixin = {
|
|||
this.preventNegativeScrollOffset = !!preventNegativeScrollOffset;
|
||||
RCTUIManager.measureLayout(
|
||||
nodeHandle,
|
||||
React.findNodeHandle(this),
|
||||
React.findNodeHandle(this.getInnerViewNode()),
|
||||
this.scrollResponderTextInputFocusError,
|
||||
this.scrollResponderInputMeasureAndScrollToKeyboard
|
||||
);
|
||||
|
@ -429,6 +441,10 @@ var ScrollResponderMixin = {
|
|||
this.addListenerOn(RCTDeviceEventEmitter, 'keyboardWillHide', this.scrollResponderKeyboardWillHide);
|
||||
this.addListenerOn(RCTDeviceEventEmitter, 'keyboardDidShow', this.scrollResponderKeyboardDidShow);
|
||||
this.addListenerOn(RCTDeviceEventEmitter, 'keyboardDidHide', this.scrollResponderKeyboardDidHide);
|
||||
warning(this.getInnerViewNode, 'You need to implement getInnerViewNode in '
|
||||
+ this.constructor.displayName + ' to get full'
|
||||
+ 'functionality from ScrollResponder mixin. See example of ListView and'
|
||||
+ ' ScrollView.');
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -286,19 +286,8 @@ var ScrollView = React.createClass({
|
|||
},
|
||||
|
||||
scrollTo: function(destY?: number, destX?: number) {
|
||||
if (Platform.OS === 'android') {
|
||||
RCTUIManager.dispatchViewManagerCommand(
|
||||
React.findNodeHandle(this),
|
||||
RCTUIManager.RCTScrollView.Commands.scrollTo,
|
||||
[destX || 0, destY || 0]
|
||||
);
|
||||
} else {
|
||||
RCTUIManager.scrollTo(
|
||||
React.findNodeHandle(this),
|
||||
destX || 0,
|
||||
destY || 0
|
||||
);
|
||||
}
|
||||
// $FlowFixMe - Don't know how to pass Mixin correctly. Postpone for now
|
||||
this.getScrollResponder().scrollResponderScrollTo(destX || 0, destY || 0);
|
||||
},
|
||||
|
||||
scrollWithoutAnimationTo: function(destY?: number, destX?: number) {
|
||||
|
@ -309,6 +298,21 @@ var ScrollView = React.createClass({
|
|||
);
|
||||
},
|
||||
|
||||
handleScroll: function(e: Event) {
|
||||
if (__DEV__) {
|
||||
if (this.props.onScroll && !this.props.scrollEventThrottle) {
|
||||
console.log(
|
||||
'You specified `onScroll` on a <ScrollView> but not ' +
|
||||
'`scrollEventThrottle`. You will only receive one event. ' +
|
||||
'Using `16` you get all the events but be aware that it may ' +
|
||||
'cause frame drops, use a bigger number if you don\'t need as ' +
|
||||
'much precision.'
|
||||
);
|
||||
}
|
||||
}
|
||||
this.scrollResponderHandleScroll(e);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var contentContainerStyle = [
|
||||
this.props.horizontal && styles.contentContainerHorizontal,
|
||||
|
@ -324,21 +328,6 @@ var ScrollView = React.createClass({
|
|||
') must by applied through the contentContainerStyle prop.'
|
||||
);
|
||||
}
|
||||
if (__DEV__) {
|
||||
if (this.props.onScroll && !this.props.scrollEventThrottle) {
|
||||
var onScroll = this.props.onScroll;
|
||||
this.props.onScroll = function() {
|
||||
console.log(
|
||||
'You specified `onScroll` on a <ScrollView> but not ' +
|
||||
'`scrollEventThrottle`. You will only receive one event. ' +
|
||||
'Using `16` you get all the events but be aware that it may ' +
|
||||
'cause frame drops, use a bigger number if you don\'t need as ' +
|
||||
'much precision.'
|
||||
);
|
||||
onScroll.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
var contentContainer =
|
||||
<View
|
||||
|
@ -373,7 +362,7 @@ var ScrollView = React.createClass({
|
|||
onStartShouldSetResponder: this.scrollResponderHandleStartShouldSetResponder,
|
||||
onStartShouldSetResponderCapture: this.scrollResponderHandleStartShouldSetResponderCapture,
|
||||
onScrollShouldSetResponder: this.scrollResponderHandleScrollShouldSetResponder,
|
||||
onScroll: this.scrollResponderHandleScroll,
|
||||
onScroll: this.handleScroll,
|
||||
onResponderGrant: this.scrollResponderHandleResponderGrant,
|
||||
onResponderTerminationRequest: this.scrollResponderHandleTerminationRequest,
|
||||
onResponderTerminate: this.scrollResponderHandleTerminate,
|
||||
|
|
|
@ -18,7 +18,6 @@ var React = require('React');
|
|||
var StyleSheet = require('StyleSheet');
|
||||
|
||||
var requireNativeComponent = require('requireNativeComponent');
|
||||
var verifyPropTypes = require('verifyPropTypes');
|
||||
|
||||
type DefaultProps = {
|
||||
values: Array<string>;
|
||||
|
|
|
@ -35,6 +35,10 @@ var StatusBarIOS = {
|
|||
animation = animation || 'none';
|
||||
RCTStatusBarManager.setHidden(hidden, animation);
|
||||
},
|
||||
|
||||
setNetworkActivityIndicatorVisible(visible: boolean) {
|
||||
RCTStatusBarManager.setNetworkActivityIndicatorVisible(visible);
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = StatusBarIOS;
|
||||
|
|
|
@ -73,8 +73,8 @@ type Event = Object;
|
|||
* types, such as a numeric keypad.
|
||||
*
|
||||
* The simplest use case is to plop down a `TextInput` and subscribe to the
|
||||
* `onChangeText` events to read the user input. There are also other events,
|
||||
* such as `onSubmitEditing` and `onFocus` that can be subscribed to. A simple
|
||||
* `onChangeText` events to read the user input. There are also other events,
|
||||
* such as `onSubmitEditing` and `onFocus` that can be subscribed to. A simple
|
||||
* example:
|
||||
*
|
||||
* ```
|
||||
|
@ -97,7 +97,6 @@ type Event = Object;
|
|||
* onSubmitEditing: true,
|
||||
* };
|
||||
*/
|
||||
|
||||
var TextInput = React.createClass({
|
||||
propTypes: {
|
||||
/**
|
||||
|
@ -115,32 +114,44 @@ var TextInput = React.createClass({
|
|||
'characters',
|
||||
]),
|
||||
/**
|
||||
* If false, disables auto-correct. Default value is true.
|
||||
* If false, disables auto-correct. The default value is true.
|
||||
*/
|
||||
autoCorrect: PropTypes.bool,
|
||||
/**
|
||||
* If true, focuses the input on componentDidMount. Default value is false.
|
||||
* If true, focuses the input on componentDidMount.
|
||||
* The default value is false.
|
||||
*/
|
||||
autoFocus: PropTypes.bool,
|
||||
/**
|
||||
* Set the position of the cursor from where editing will begin.
|
||||
* @platorm android
|
||||
*/
|
||||
textAlign: PropTypes.oneOf([
|
||||
'start',
|
||||
'center',
|
||||
'end',
|
||||
]),
|
||||
/**
|
||||
* Aligns text vertically within the TextInput.
|
||||
* @platform android
|
||||
*/
|
||||
textAlignVertical: PropTypes.oneOf([
|
||||
'top',
|
||||
'center',
|
||||
'bottom',
|
||||
]),
|
||||
/**
|
||||
* If false, text is not editable. Default value is true.
|
||||
* If false, text is not editable. The default value is true.
|
||||
* @platform ios
|
||||
*/
|
||||
editable: PropTypes.bool,
|
||||
/**
|
||||
* Determines which keyboard to open, e.g.`numeric`.
|
||||
*
|
||||
* The following values work across platforms:
|
||||
* - default
|
||||
* - numeric
|
||||
* - email-address
|
||||
*/
|
||||
keyboardType: PropTypes.oneOf([
|
||||
// Cross-platform
|
||||
|
@ -160,6 +171,7 @@ var TextInput = React.createClass({
|
|||
]),
|
||||
/**
|
||||
* Determines how the return key should look.
|
||||
* @platform ios
|
||||
*/
|
||||
returnKeyType: PropTypes.oneOf([
|
||||
'default',
|
||||
|
@ -175,17 +187,20 @@ var TextInput = React.createClass({
|
|||
'emergency-call',
|
||||
]),
|
||||
/**
|
||||
* Limits the maximum number of characters that can be entered. Use this
|
||||
* Limits the maximum number of characters that can be entered. Use this
|
||||
* instead of implementing the logic in JS to avoid flicker.
|
||||
* @platform ios
|
||||
*/
|
||||
maxLength: PropTypes.number,
|
||||
/**
|
||||
* If true, the keyboard disables the return key when there is no text and
|
||||
* automatically enables it when there is text. Default value is false.
|
||||
* automatically enables it when there is text. The default value is false.
|
||||
* @platform ios
|
||||
*/
|
||||
enablesReturnKeyAutomatically: PropTypes.bool,
|
||||
/**
|
||||
* If true, the text input can be multiple lines. Default value is false.
|
||||
* If true, the text input can be multiple lines.
|
||||
* The default value is false.
|
||||
*/
|
||||
multiline: PropTypes.bool,
|
||||
/**
|
||||
|
@ -214,14 +229,9 @@ var TextInput = React.createClass({
|
|||
*/
|
||||
onSubmitEditing: PropTypes.func,
|
||||
/**
|
||||
* Invoked on mount and layout changes with {x, y, width, height}.
|
||||
* Invoked on mount and layout changes with `{x, y, width, height}`.
|
||||
*/
|
||||
onLayout: PropTypes.func,
|
||||
/**
|
||||
* If true, the text input obscures the text entered so that sensitive text
|
||||
* like passwords stay secure. Default value is false.
|
||||
*/
|
||||
password: PropTypes.bool,
|
||||
/**
|
||||
* The string that will be rendered before text input has been entered
|
||||
*/
|
||||
|
@ -230,17 +240,23 @@ var TextInput = React.createClass({
|
|||
* The text color of the placeholder string
|
||||
*/
|
||||
placeholderTextColor: PropTypes.string,
|
||||
/**
|
||||
* If true, the text input obscures the text entered so that sensitive text
|
||||
* like passwords stay secure. The default value is false.
|
||||
*/
|
||||
secureTextEntry: PropTypes.bool,
|
||||
/**
|
||||
* See DocumentSelectionState.js, some state that is responsible for
|
||||
* maintaining selection information for a document
|
||||
* @platform ios
|
||||
*/
|
||||
selectionState: PropTypes.instanceOf(DocumentSelectionState),
|
||||
/**
|
||||
* The value to show for the text input. TextInput is a controlled
|
||||
* The value to show for the text input. TextInput is a controlled
|
||||
* component, which means the native value will be forced to match this
|
||||
* value prop if provided. For most uses this works great, but in some
|
||||
* value prop if provided. For most uses this works great, but in some
|
||||
* cases this may cause flickering - one common cause is preventing edits
|
||||
* by keeping value the same. In addition to simply setting the same value,
|
||||
* by keeping value the same. In addition to simply setting the same value,
|
||||
* either set `editable={false}`, or set/update `maxLength` to prevent
|
||||
* unwanted edits without flicker.
|
||||
*/
|
||||
|
@ -253,6 +269,7 @@ var TextInput = React.createClass({
|
|||
defaultValue: PropTypes.string,
|
||||
/**
|
||||
* When the clear button should appear on the right side of the text view
|
||||
* @platform ios
|
||||
*/
|
||||
clearButtonMode: PropTypes.oneOf([
|
||||
'never',
|
||||
|
@ -262,10 +279,12 @@ var TextInput = React.createClass({
|
|||
]),
|
||||
/**
|
||||
* If true, clears the text field automatically when editing begins
|
||||
* @platform ios
|
||||
*/
|
||||
clearTextOnFocus: PropTypes.bool,
|
||||
/**
|
||||
* If true, selected the text automatically when editing begins
|
||||
* If true, all text will automatically be selected on focus
|
||||
* @platform ios
|
||||
*/
|
||||
selectTextOnFocus: PropTypes.bool,
|
||||
/**
|
||||
|
@ -273,11 +292,12 @@ var TextInput = React.createClass({
|
|||
*/
|
||||
style: Text.propTypes.style,
|
||||
/**
|
||||
* Used to locate this view in end-to-end tests.
|
||||
* Used to locate this view in end-to-end tests
|
||||
*/
|
||||
testID: PropTypes.string,
|
||||
/**
|
||||
* The color of the textInput underline. Is only supported on Android.
|
||||
* The color of the textInput underline.
|
||||
* @platform android
|
||||
*/
|
||||
underlineColorAndroid: PropTypes.string,
|
||||
},
|
||||
|
@ -346,6 +366,10 @@ var TextInput = React.createClass({
|
|||
isInAParentText: React.PropTypes.bool
|
||||
},
|
||||
|
||||
clear: function() {
|
||||
this.setNativeProps({text: ''});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (Platform.OS === 'ios') {
|
||||
return this._renderIOS();
|
||||
|
|
|
@ -4,6 +4,6 @@ For React Native Custom Components software
|
|||
|
||||
Copyright (c) 2015, Facebook, Inc. All rights reserved.
|
||||
|
||||
Facebook, Inc. (“Facebook”) owns all right, title and interest, including all intellectual property and other proprietary rights, in and to the React Native Custom Components software (the “Software”). Subject to your compliance with these terms, you are hereby granted a non-exclusive, worldwide, royalty-free copyright license to (1) use and copy the Software; and (2) reproduce and distribute the Software as part of your own software (“Your Software”). Facebook reserves all rights not expressly granted to you in this license agreement.
|
||||
Facebook, Inc. ("Facebook") owns all right, title and interest, including all intellectual property and other proprietary rights, in and to the React Native Custom Components software (the "Software"). Subject to your compliance with these terms, you are hereby granted a non-exclusive, worldwide, royalty-free copyright license to (1) use and copy the Software; and (2) reproduce and distribute the Software as part of your own software ("Your Software"). Facebook reserves all rights not expressly granted to you in this license agreement.
|
||||
|
||||
THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES (INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE) ARE DISCLAIMED. IN NO EVENT SHALL FACEBOOK OR ITS AFFILIATES, OFFICERS, DIRECTORS OR EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/**
|
||||
* Copyright (c) 2015, Facebook, Inc. All rights reserved.
|
||||
*
|
||||
* Facebook, Inc. (“Facebook”) owns all right, title and interest, including
|
||||
* Facebook, Inc. ("Facebook") owns all right, title and interest, including
|
||||
* all intellectual property and other proprietary rights, in and to the React
|
||||
* Native CustomComponents software (the “Software”). Subject to your
|
||||
* Native CustomComponents software (the "Software"). Subject to your
|
||||
* compliance with these terms, you are hereby granted a non-exclusive,
|
||||
* worldwide, royalty-free copyright license to (1) use and copy the Software;
|
||||
* and (2) reproduce and distribute the Software as part of your own software
|
||||
* (“Your Software”). Facebook reserves all rights not expressly granted to
|
||||
* ("Your Software"). Facebook reserves all rights not expressly granted to
|
||||
* you in this license agreement.
|
||||
*
|
||||
* THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS
|
||||
|
@ -252,6 +252,10 @@ var ListView = React.createClass({
|
|||
};
|
||||
},
|
||||
|
||||
getInnerViewNode: function() {
|
||||
return this.refs[SCROLLVIEW_REF].getInnerViewNode();
|
||||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
// this data should never trigger a render pass, so don't put in state
|
||||
this.scrollProperties = {
|
||||
|
@ -386,14 +390,13 @@ var ListView = React.createClass({
|
|||
Object.assign(props, {
|
||||
onScroll: this._onScroll,
|
||||
stickyHeaderIndices: sectionHeaderIndices,
|
||||
children: [header, bodyComponents, footer],
|
||||
});
|
||||
|
||||
// TODO(ide): Use function refs so we can compose with the scroll
|
||||
// component's original ref instead of clobbering it
|
||||
return React.cloneElement(renderScrollComponent(props), {
|
||||
ref: SCROLLVIEW_REF,
|
||||
});
|
||||
}, header, bodyComponents, footer);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/**
|
||||
* Copyright (c) 2015, Facebook, Inc. All rights reserved.
|
||||
*
|
||||
* Facebook, Inc. (“Facebook”) owns all right, title and interest, including
|
||||
* Facebook, Inc. ("Facebook") owns all right, title and interest, including
|
||||
* all intellectual property and other proprietary rights, in and to the React
|
||||
* Native CustomComponents software (the “Software”). Subject to your
|
||||
* Native CustomComponents software (the "Software"). Subject to your
|
||||
* compliance with these terms, you are hereby granted a non-exclusive,
|
||||
* worldwide, royalty-free copyright license to (1) use and copy the Software;
|
||||
* and (2) reproduce and distribute the Software as part of your own software
|
||||
* (“Your Software”). Facebook reserves all rights not expressly granted to
|
||||
* ("Your Software"). Facebook reserves all rights not expressly granted to
|
||||
* you in this license agreement.
|
||||
*
|
||||
* THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/**
|
||||
* Copyright (c) 2015, Facebook, Inc. All rights reserved.
|
||||
*
|
||||
* Facebook, Inc. (“Facebook”) owns all right, title and interest, including
|
||||
* Facebook, Inc. ("Facebook") owns all right, title and interest, including
|
||||
* all intellectual property and other proprietary rights, in and to the React
|
||||
* Native CustomComponents software (the “Software”). Subject to your
|
||||
* Native CustomComponents software (the "Software"). Subject to your
|
||||
* compliance with these terms, you are hereby granted a non-exclusive,
|
||||
* worldwide, royalty-free copyright license to (1) use and copy the Software;
|
||||
* and (2) reproduce and distribute the Software as part of your own software
|
||||
* (“Your Software”). Facebook reserves all rights not expressly granted to
|
||||
* ("Your Software"). Facebook reserves all rights not expressly granted to
|
||||
* you in this license agreement.
|
||||
*
|
||||
* THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/**
|
||||
* Copyright (c) 2015, Facebook, Inc. All rights reserved.
|
||||
*
|
||||
* Facebook, Inc. (“Facebook”) owns all right, title and interest, including
|
||||
* Facebook, Inc. ("Facebook") owns all right, title and interest, including
|
||||
* all intellectual property and other proprietary rights, in and to the React
|
||||
* Native CustomComponents software (the “Software”). Subject to your
|
||||
* Native CustomComponents software (the "Software"). Subject to your
|
||||
* compliance with these terms, you are hereby granted a non-exclusive,
|
||||
* worldwide, royalty-free copyright license to (1) use and copy the Software;
|
||||
* and (2) reproduce and distribute the Software as part of your own software
|
||||
* (“Your Software”). Facebook reserves all rights not expressly granted to
|
||||
* ("Your Software"). Facebook reserves all rights not expressly granted to
|
||||
* you in this license agreement.
|
||||
*
|
||||
* THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/**
|
||||
* Copyright (c) 2015, Facebook, Inc. All rights reserved.
|
||||
*
|
||||
* Facebook, Inc. (“Facebook”) owns all right, title and interest, including
|
||||
* Facebook, Inc. ("Facebook") owns all right, title and interest, including
|
||||
* all intellectual property and other proprietary rights, in and to the React
|
||||
* Native CustomComponents software (the “Software”). Subject to your
|
||||
* Native CustomComponents software (the "Software"). Subject to your
|
||||
* compliance with these terms, you are hereby granted a non-exclusive,
|
||||
* worldwide, royalty-free copyright license to (1) use and copy the Software;
|
||||
* and (2) reproduce and distribute the Software as part of your own software
|
||||
* (“Your Software”). Facebook reserves all rights not expressly granted to
|
||||
* ("Your Software"). Facebook reserves all rights not expressly granted to
|
||||
* you in this license agreement.
|
||||
*
|
||||
* THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS
|
||||
|
|
|
@ -135,7 +135,7 @@ class RouteStack {
|
|||
);
|
||||
|
||||
var routes = this._routes.set(index, route);
|
||||
return this._update(this._index, routes);
|
||||
return this._update(index, routes);
|
||||
}
|
||||
|
||||
_update(index: number, routes: List): RouteStack {
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/**
|
||||
* Copyright (c) 2015, Facebook, Inc. All rights reserved.
|
||||
*
|
||||
* Facebook, Inc. (“Facebook”) owns all right, title and interest, including
|
||||
* Facebook, Inc. ("Facebook") owns all right, title and interest, including
|
||||
* all intellectual property and other proprietary rights, in and to the React
|
||||
* Native CustomComponents software (the “Software”). Subject to your
|
||||
* Native CustomComponents software (the "Software"). Subject to your
|
||||
* compliance with these terms, you are hereby granted a non-exclusive,
|
||||
* worldwide, royalty-free copyright license to (1) use and copy the Software;
|
||||
* and (2) reproduce and distribute the Software as part of your own software
|
||||
* (“Your Software”). Facebook reserves all rights not expressly granted to
|
||||
* ("Your Software"). Facebook reserves all rights not expressly granted to
|
||||
* you in this license agreement.
|
||||
*
|
||||
* THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
/**
|
||||
* Copyright (c) 2015, Facebook, Inc. All rights reserved.
|
||||
*
|
||||
* Facebook, Inc. (“Facebook”) owns all right, title and interest, including
|
||||
* Facebook, Inc. ("Facebook") owns all right, title and interest, including
|
||||
* all intellectual property and other proprietary rights, in and to the React
|
||||
* Native CustomComponents software (the “Software”). Subject to your
|
||||
* Native CustomComponents software (the "Software"). Subject to your
|
||||
* compliance with these terms, you are hereby granted a non-exclusive,
|
||||
* worldwide, royalty-free copyright license to (1) use and copy the Software;
|
||||
* and (2) reproduce and distribute the Software as part of your own software
|
||||
* (“Your Software”). Facebook reserves all rights not expressly granted to
|
||||
* ("Your Software"). Facebook reserves all rights not expressly granted to
|
||||
* you in this license agreement.
|
||||
*
|
||||
* THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/**
|
||||
* Copyright (c) 2015, Facebook, Inc. All rights reserved.
|
||||
*
|
||||
* Facebook, Inc. (“Facebook”) owns all right, title and interest, including
|
||||
* Facebook, Inc. ("Facebook") owns all right, title and interest, including
|
||||
* all intellectual property and other proprietary rights, in and to the React
|
||||
* Native CustomComponents software (the “Software”). Subject to your
|
||||
* Native CustomComponents software (the "Software"). Subject to your
|
||||
* compliance with these terms, you are hereby granted a non-exclusive,
|
||||
* worldwide, royalty-free copyright license to (1) use and copy the Software;
|
||||
* and (2) reproduce and distribute the Software as part of your own software
|
||||
* (“Your Software”). Facebook reserves all rights not expressly granted to
|
||||
* ("Your Software"). Facebook reserves all rights not expressly granted to
|
||||
* you in this license agreement.
|
||||
*
|
||||
* THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/**
|
||||
* Copyright (c) 2015, Facebook, Inc. All rights reserved.
|
||||
*
|
||||
* Facebook, Inc. (“Facebook”) owns all right, title and interest, including
|
||||
* Facebook, Inc. ("Facebook") owns all right, title and interest, including
|
||||
* all intellectual property and other proprietary rights, in and to the React
|
||||
* Native CustomComponents software (the “Software”). Subject to your
|
||||
* Native CustomComponents software (the "Software"). Subject to your
|
||||
* compliance with these terms, you are hereby granted a non-exclusive,
|
||||
* worldwide, royalty-free copyright license to (1) use and copy the Software;
|
||||
* and (2) reproduce and distribute the Software as part of your own software
|
||||
* (“Your Software”). Facebook reserves all rights not expressly granted to
|
||||
* ("Your Software"). Facebook reserves all rights not expressly granted to
|
||||
* you in this license agreement.
|
||||
*
|
||||
* THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS
|
||||
|
@ -201,7 +201,7 @@ describe('NavigationRouteStack:', () => {
|
|||
|
||||
expect(stack2).not.toBe(stack1);
|
||||
expect(stack2.toArray()).toEqual(['x', 'b']);
|
||||
expect(stack2.index).toBe(1);
|
||||
expect(stack2.index).toBe(0);
|
||||
});
|
||||
|
||||
it('replaces route at negative index', () => {
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/**
|
||||
* Copyright (c) 2015, Facebook, Inc. All rights reserved.
|
||||
*
|
||||
* Facebook, Inc. (“Facebook”) owns all right, title and interest, including
|
||||
* Facebook, Inc. ("Facebook") owns all right, title and interest, including
|
||||
* all intellectual property and other proprietary rights, in and to the React
|
||||
* Native CustomComponents software (the “Software”). Subject to your
|
||||
* Native CustomComponents software (the "Software"). Subject to your
|
||||
* compliance with these terms, you are hereby granted a non-exclusive,
|
||||
* worldwide, royalty-free copyright license to (1) use and copy the Software;
|
||||
* and (2) reproduce and distribute the Software as part of your own software
|
||||
* (“Your Software”). Facebook reserves all rights not expressly granted to
|
||||
* ("Your Software"). Facebook reserves all rights not expressly granted to
|
||||
* you in this license agreement.
|
||||
*
|
||||
* THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS
|
||||
|
@ -56,8 +56,9 @@ var PropTypes = React.PropTypes;
|
|||
var SCREEN_WIDTH = Dimensions.get('window').width;
|
||||
var SCREEN_HEIGHT = Dimensions.get('window').height;
|
||||
var SCENE_DISABLED_NATIVE_PROPS = {
|
||||
pointerEvents: 'none',
|
||||
style: {
|
||||
left: SCREEN_WIDTH,
|
||||
top: SCREEN_HEIGHT,
|
||||
opacity: 0,
|
||||
},
|
||||
};
|
||||
|
@ -107,7 +108,7 @@ var styles = StyleSheet.create({
|
|||
top: 0,
|
||||
},
|
||||
disabledScene: {
|
||||
left: SCREEN_WIDTH,
|
||||
top: SCREEN_HEIGHT,
|
||||
},
|
||||
transitioner: {
|
||||
flex: 1,
|
||||
|
@ -529,15 +530,18 @@ var Navigator = React.createClass({
|
|||
_enableScene: function(sceneIndex) {
|
||||
// First, determine what the defined styles are for scenes in this navigator
|
||||
var sceneStyle = flattenStyle([styles.baseScene, this.props.sceneStyle]);
|
||||
// Then restore the left value for this scene
|
||||
// Then restore the pointer events and top value for this scene
|
||||
var enabledSceneNativeProps = {
|
||||
left: sceneStyle.left,
|
||||
pointerEvents: 'auto',
|
||||
style: {
|
||||
top: sceneStyle.top,
|
||||
},
|
||||
};
|
||||
if (sceneIndex !== this.state.transitionFromIndex &&
|
||||
sceneIndex !== this.state.presentedIndex) {
|
||||
// If we are not in a transition from this index, make sure opacity is 0
|
||||
// to prevent the enabled scene from flashing over the presented scene
|
||||
enabledSceneNativeProps.opacity = 0;
|
||||
enabledSceneNativeProps.style.opacity = 0;
|
||||
}
|
||||
this.refs['scene_' + sceneIndex] &&
|
||||
this.refs['scene_' + sceneIndex].setNativeProps(enabledSceneNativeProps);
|
||||
|
@ -1021,8 +1025,10 @@ var Navigator = React.createClass({
|
|||
|
||||
_renderScene: function(route, i) {
|
||||
var disabledSceneStyle = null;
|
||||
var disabledScenePointerEvents = 'auto';
|
||||
if (i !== this.state.presentedIndex) {
|
||||
disabledSceneStyle = styles.disabledScene;
|
||||
disabledScenePointerEvents = 'none';
|
||||
}
|
||||
return (
|
||||
<View
|
||||
|
@ -1031,6 +1037,7 @@ var Navigator = React.createClass({
|
|||
onStartShouldSetResponderCapture={() => {
|
||||
return (this.state.transitionFromIndex != null) || (this.state.transitionFromIndex != null);
|
||||
}}
|
||||
pointerEvents={disabledScenePointerEvents}
|
||||
style={[styles.baseScene, this.props.sceneStyle, disabledSceneStyle]}>
|
||||
{this.props.renderScene(
|
||||
route,
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/**
|
||||
* Copyright (c) 2015, Facebook, Inc. All rights reserved.
|
||||
*
|
||||
* Facebook, Inc. (“Facebook”) owns all right, title and interest, including
|
||||
* Facebook, Inc. ("Facebook") owns all right, title and interest, including
|
||||
* all intellectual property and other proprietary rights, in and to the React
|
||||
* Native CustomComponents software (the “Software”). Subject to your
|
||||
* Native CustomComponents software (the "Software"). Subject to your
|
||||
* compliance with these terms, you are hereby granted a non-exclusive,
|
||||
* worldwide, royalty-free copyright license to (1) use and copy the Software;
|
||||
* and (2) reproduce and distribute the Software as part of your own software
|
||||
* (“Your Software”). Facebook reserves all rights not expressly granted to
|
||||
* ("Your Software"). Facebook reserves all rights not expressly granted to
|
||||
* you in this license agreement.
|
||||
*
|
||||
* THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/**
|
||||
* Copyright (c) 2015, Facebook, Inc. All rights reserved.
|
||||
*
|
||||
* Facebook, Inc. (“Facebook”) owns all right, title and interest, including
|
||||
* Facebook, Inc. ("Facebook") owns all right, title and interest, including
|
||||
* all intellectual property and other proprietary rights, in and to the React
|
||||
* Native CustomComponents software (the “Software”). Subject to your
|
||||
* Native CustomComponents software (the "Software"). Subject to your
|
||||
* compliance with these terms, you are hereby granted a non-exclusive,
|
||||
* worldwide, royalty-free copyright license to (1) use and copy the Software;
|
||||
* and (2) reproduce and distribute the Software as part of your own software
|
||||
* (“Your Software”). Facebook reserves all rights not expressly granted to
|
||||
* ("Your Software"). Facebook reserves all rights not expressly granted to
|
||||
* you in this license agreement.
|
||||
*
|
||||
* THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/**
|
||||
* Copyright (c) 2015, Facebook, Inc. All rights reserved.
|
||||
*
|
||||
* Facebook, Inc. (“Facebook”) owns all right, title and interest, including
|
||||
* Facebook, Inc. ("Facebook") owns all right, title and interest, including
|
||||
* all intellectual property and other proprietary rights, in and to the React
|
||||
* Native CustomComponents software (the “Software”). Subject to your
|
||||
* Native CustomComponents software (the "Software"). Subject to your
|
||||
* compliance with these terms, you are hereby granted a non-exclusive,
|
||||
* worldwide, royalty-free copyright license to (1) use and copy the Software;
|
||||
* and (2) reproduce and distribute the Software as part of your own software
|
||||
* (“Your Software”). Facebook reserves all rights not expressly granted to
|
||||
* ("Your Software"). Facebook reserves all rights not expressly granted to
|
||||
* you in this license agreement.
|
||||
*
|
||||
* THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/**
|
||||
* Copyright (c) 2015, Facebook, Inc. All rights reserved.
|
||||
*
|
||||
* Facebook, Inc. (“Facebook”) owns all right, title and interest, including
|
||||
* Facebook, Inc. ("Facebook") owns all right, title and interest, including
|
||||
* all intellectual property and other proprietary rights, in and to the React
|
||||
* Native CustomComponents software (the “Software”). Subject to your
|
||||
* Native CustomComponents software (the "Software"). Subject to your
|
||||
* compliance with these terms, you are hereby granted a non-exclusive,
|
||||
* worldwide, royalty-free copyright license to (1) use and copy the Software;
|
||||
* and (2) reproduce and distribute the Software as part of your own software
|
||||
* (“Your Software”). Facebook reserves all rights not expressly granted to
|
||||
* ("Your Software"). Facebook reserves all rights not expressly granted to
|
||||
* you in this license agreement.
|
||||
*
|
||||
* THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/**
|
||||
* Copyright (c) 2015, Facebook, Inc. All rights reserved.
|
||||
*
|
||||
* Facebook, Inc. (“Facebook”) owns all right, title and interest, including
|
||||
* Facebook, Inc. ("Facebook") owns all right, title and interest, including
|
||||
* all intellectual property and other proprietary rights, in and to the React
|
||||
* Native CustomComponents software (the “Software”). Subject to your
|
||||
* Native CustomComponents software (the "Software"). Subject to your
|
||||
* compliance with these terms, you are hereby granted a non-exclusive,
|
||||
* worldwide, royalty-free copyright license to (1) use and copy the Software;
|
||||
* and (2) reproduce and distribute the Software as part of your own software
|
||||
* (“Your Software”). Facebook reserves all rights not expressly granted to
|
||||
* ("Your Software"). Facebook reserves all rights not expressly granted to
|
||||
* you in this license agreement.
|
||||
*
|
||||
* THE SOFTWARE AND DOCUMENTATION, IF ANY, ARE PROVIDED "AS IS" AND ANY EXPRESS
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
/**
|
||||
* 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.
|
||||
*
|
||||
* @providesModule setupDevtools
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
function setupDevtools() {
|
||||
var messageListeners = [];
|
||||
var closeListeners = [];
|
||||
var ws = new window.WebSocket('ws://localhost:8081/devtools');
|
||||
// this is accessed by the eval'd backend code
|
||||
var FOR_BACKEND = { // eslint-disable-line no-unused-vars
|
||||
resolveRNStyle: require('flattenStyle'),
|
||||
wall: {
|
||||
listen(fn) {
|
||||
messageListeners.push(fn);
|
||||
},
|
||||
onClose(fn) {
|
||||
closeListeners.push(fn);
|
||||
},
|
||||
send(data) {
|
||||
ws.send(JSON.stringify(data));
|
||||
},
|
||||
},
|
||||
};
|
||||
ws.onclose = () => {
|
||||
console.warn('devtools socket closed');
|
||||
closeListeners.forEach(fn => fn());
|
||||
};
|
||||
ws.onerror = error => {
|
||||
console.warn('devtools socket errored', error);
|
||||
closeListeners.forEach(fn => fn());
|
||||
};
|
||||
ws.onopen = function () {
|
||||
tryToConnect();
|
||||
};
|
||||
|
||||
function tryToConnect() {
|
||||
ws.send('attach:agent');
|
||||
var _interval = setInterval(() => ws.send('attach:agent'), 500);
|
||||
ws.onmessage = evt => {
|
||||
if (evt.data.indexOf('eval:') === 0) {
|
||||
clearInterval(_interval);
|
||||
initialize(evt.data.slice('eval:'.length));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function initialize(text) {
|
||||
try {
|
||||
// FOR_BACKEND is used by the eval'd code
|
||||
eval(text); // eslint-disable-line no-eval
|
||||
} catch (e) {
|
||||
console.error('Failed to eval' + e.message);
|
||||
return;
|
||||
}
|
||||
window.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject({
|
||||
CurrentOwner: require('ReactCurrentOwner'),
|
||||
InstanceHandles: require('ReactInstanceHandles'),
|
||||
Mount: require('ReactNativeMount'),
|
||||
Reconciler: require('ReactReconciler'),
|
||||
TextComponent: require('ReactNativeTextComponent'),
|
||||
});
|
||||
ws.onmessage = handleMessage;
|
||||
}
|
||||
|
||||
function handleMessage(evt) {
|
||||
var data;
|
||||
try {
|
||||
data = JSON.parse(evt.data);
|
||||
} catch (e) {
|
||||
return console.error('failed to parse json: ' + evt.data);
|
||||
}
|
||||
// the devtools closed
|
||||
if (data.$close || data.$error) {
|
||||
closeListeners.forEach(fn => fn());
|
||||
window.__REACT_DEVTOOLS_GLOBAL_HOOK__.emit('shutdown');
|
||||
tryToConnect();
|
||||
return;
|
||||
}
|
||||
if (data.$open) {
|
||||
return; // ignore
|
||||
}
|
||||
messageListeners.forEach(fn => {
|
||||
try {
|
||||
fn(data);
|
||||
} catch (e) {
|
||||
// jsc doesn't play so well with tracebacks that go into eval'd code,
|
||||
// so the stack trace here will stop at the `eval()` call. Getting the
|
||||
// message that caused the error is the best we can do for now.
|
||||
console.log(data);
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = setupDevtools;
|
|
@ -151,6 +151,7 @@
|
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
@ -190,6 +191,7 @@
|
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
|
|
@ -26,7 +26,6 @@ var flattenStyle = require('flattenStyle');
|
|||
var invariant = require('invariant');
|
||||
var requireNativeComponent = require('requireNativeComponent');
|
||||
var resolveAssetSource = require('resolveAssetSource');
|
||||
var verifyPropTypes = require('verifyPropTypes');
|
||||
var warning = require('warning');
|
||||
|
||||
/**
|
||||
|
@ -53,7 +52,6 @@ var warning = require('warning');
|
|||
* },
|
||||
* ```
|
||||
*/
|
||||
|
||||
var Image = React.createClass({
|
||||
propTypes: {
|
||||
style: StyleSheetPropType(ImageStylePropTypes),
|
||||
|
@ -68,16 +66,20 @@ var Image = React.createClass({
|
|||
/**
|
||||
* A static image to display while downloading the final image off the
|
||||
* network.
|
||||
* @platform ios
|
||||
*/
|
||||
defaultSource: PropTypes.shape({
|
||||
uri: PropTypes.string,
|
||||
}),
|
||||
/**
|
||||
* Whether this element should be revealed as an accessible element.
|
||||
* When true, indicates the image is an accessibility element.
|
||||
* @platform ios
|
||||
*/
|
||||
accessible: PropTypes.bool,
|
||||
/**
|
||||
* Custom string to display for accessibility.
|
||||
* The text that's read by the screen reader when the user interacts with
|
||||
* the image.
|
||||
* @platform ios
|
||||
*/
|
||||
accessibilityLabel: PropTypes.string,
|
||||
/**
|
||||
|
@ -86,6 +88,7 @@ var Image = React.createClass({
|
|||
* of the image will be stretched. This is useful for creating resizable
|
||||
* rounded buttons, shadows, and other resizable assets. More info on
|
||||
* [Apple documentation](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImage_Class/index.html#//apple_ref/occ/instm/UIImage/resizableImageWithCapInsets)
|
||||
* @platform ios
|
||||
*/
|
||||
capInsets: EdgeInsetsPropType,
|
||||
/**
|
||||
|
@ -100,32 +103,32 @@ var Image = React.createClass({
|
|||
testID: PropTypes.string,
|
||||
/**
|
||||
* Invoked on mount and layout changes with
|
||||
*
|
||||
* {nativeEvent: {layout: {x, y, width, height}}}.
|
||||
* `{nativeEvent: {layout: {x, y, width, height}}}`.
|
||||
*/
|
||||
onLayout: PropTypes.func,
|
||||
/**
|
||||
* Invoked on load start
|
||||
* @platform ios
|
||||
*/
|
||||
onLoadStart: PropTypes.func,
|
||||
/**
|
||||
* Invoked on download progress with
|
||||
*
|
||||
* {nativeEvent: {loaded, total}}.
|
||||
* Invoked on download progress with `{nativeEvent: {loaded, total}}`
|
||||
* @platform ios
|
||||
*/
|
||||
onProgress: PropTypes.func,
|
||||
/**
|
||||
* Invoked on load error
|
||||
*
|
||||
* {nativeEvent: {error}}.
|
||||
* Invoked on load error with `{nativeEvent: {error}}`
|
||||
* @platform ios
|
||||
*/
|
||||
onError: PropTypes.func,
|
||||
/**
|
||||
* Invoked when load completes successfully
|
||||
* @platform ios
|
||||
*/
|
||||
onLoad: PropTypes.func,
|
||||
/**
|
||||
* Invoked when load either succeeds or fails
|
||||
* @platform ios
|
||||
*/
|
||||
onLoadEnd: PropTypes.func,
|
||||
},
|
||||
|
@ -146,6 +149,12 @@ var Image = React.createClass({
|
|||
},
|
||||
|
||||
render: function() {
|
||||
for (var prop in cfg.nativeOnly) {
|
||||
if (this.props[prop] !== undefined) {
|
||||
console.warn('Prop `' + prop + ' = ' + this.props[prop] + '` should ' +
|
||||
'not be set directly on Image.');
|
||||
}
|
||||
}
|
||||
var source = resolveAssetSource(this.props.source) || {};
|
||||
var defaultSource = (this.props.defaultSource && resolveAssetSource(this.props.defaultSource)) || {};
|
||||
|
||||
|
@ -176,7 +185,15 @@ var styles = StyleSheet.create({
|
|||
},
|
||||
});
|
||||
|
||||
var RCTImageView = requireNativeComponent('RCTImageView', null);
|
||||
var RCTNetworkImageView = (NativeModules.NetworkImageViewManager) ? requireNativeComponent('RCTNetworkImageView', null) : RCTImageView;
|
||||
var cfg = {
|
||||
nativeOnly: {
|
||||
src: true,
|
||||
defaultImageSrc: true,
|
||||
imageTag: true,
|
||||
progressHandlerRegistered: true,
|
||||
},
|
||||
};
|
||||
var RCTImageView = requireNativeComponent('RCTImageView', Image, cfg);
|
||||
var RCTNetworkImageView = (NativeModules.NetworkImageViewManager) ? requireNativeComponent('RCTNetworkImageView', Image, cfg) : RCTImageView;
|
||||
|
||||
module.exports = Image;
|
||||
|
|
|
@ -29,12 +29,12 @@ RCT_EXPORT_METHOD(saveImageWithTag:(NSString *)imageTag
|
|||
successCallback:(RCTResponseSenderBlock)successCallback
|
||||
errorCallback:(RCTResponseErrorBlock)errorCallback)
|
||||
{
|
||||
[RCTImageLoader loadImageWithTag:imageTag bridge:_bridge callback:^(NSError *loadError, UIImage *loadedImage) {
|
||||
[_bridge.imageLoader loadImageWithTag:imageTag callback:^(NSError *loadError, UIImage *loadedImage) {
|
||||
if (loadError) {
|
||||
errorCallback(loadError);
|
||||
return;
|
||||
}
|
||||
[[RCTImageLoader assetsLibrary] writeImageToSavedPhotosAlbum:[loadedImage CGImage] metadata:nil completionBlock:^(NSURL *assetURL, NSError *saveError) {
|
||||
[_bridge.assetsLibrary writeImageToSavedPhotosAlbum:[loadedImage CGImage] metadata:nil completionBlock:^(NSURL *assetURL, NSError *saveError) {
|
||||
if (saveError) {
|
||||
RCTLogWarn(@"Error saving cropped image: %@", saveError);
|
||||
errorCallback(saveError);
|
||||
|
@ -96,7 +96,7 @@ RCT_EXPORT_METHOD(getPhotos:(NSDictionary *)params
|
|||
BOOL __block calledCallback = NO;
|
||||
NSMutableArray *assets = [[NSMutableArray alloc] init];
|
||||
|
||||
[[RCTImageLoader assetsLibrary] enumerateGroupsWithTypes:groupTypes usingBlock:^(ALAssetsGroup *group, BOOL *stopGroups) {
|
||||
[_bridge.assetsLibrary enumerateGroupsWithTypes:groupTypes usingBlock:^(ALAssetsGroup *group, BOOL *stopGroups) {
|
||||
if (group && (groupName == nil || [groupName isEqualToString:[group valueForProperty:ALAssetsGroupPropertyName]])) {
|
||||
|
||||
if (assetType == nil || [assetType isEqualToString:@"Photos"]) {
|
||||
|
|
|
@ -211,6 +211,7 @@
|
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
@ -250,6 +251,7 @@
|
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
|
|
@ -9,37 +9,31 @@
|
|||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "RCTBridge.h"
|
||||
|
||||
@class ALAssetsLibrary;
|
||||
@class RCTBridge;
|
||||
|
||||
typedef void (^RCTImageLoaderProgressBlock)(int64_t written, int64_t total);
|
||||
typedef void (^RCTImageLoaderCompletionBlock)(NSError *error, id /* UIImage or CAAnimation */);
|
||||
typedef void (^RCTImageLoaderCompletionBlock)(NSError *error, id image /* UIImage or CAAnimation */);
|
||||
typedef void (^RCTImageLoaderCancellationBlock)(void);
|
||||
|
||||
@interface RCTImageLoader : NSObject
|
||||
@interface RCTImageLoader : NSObject <RCTBridgeModule>
|
||||
|
||||
/**
|
||||
* The shared asset library instance.
|
||||
* Loads the specified image at the highest available resolution.
|
||||
* Can be called from any thread, will always call callback on main thread.
|
||||
*/
|
||||
+ (ALAssetsLibrary *)assetsLibrary;
|
||||
|
||||
/**
|
||||
* Can be called from any thread.
|
||||
* Will always call callback on main thread.
|
||||
*/
|
||||
+ (RCTImageLoaderCancellationBlock)loadImageWithTag:(NSString *)imageTag
|
||||
bridge:(RCTBridge *)bridge
|
||||
- (RCTImageLoaderCancellationBlock)loadImageWithTag:(NSString *)imageTag
|
||||
callback:(RCTImageLoaderCompletionBlock)callback;
|
||||
|
||||
/**
|
||||
* As above, but includes target size, scale and resizeMode, which are used to
|
||||
* select the optimal dimensions for the loaded image.
|
||||
*/
|
||||
+ (RCTImageLoaderCancellationBlock)loadImageWithTag:(NSString *)imageTag
|
||||
- (RCTImageLoaderCancellationBlock)loadImageWithTag:(NSString *)imageTag
|
||||
size:(CGSize)size
|
||||
scale:(CGFloat)scale
|
||||
resizeMode:(UIViewContentMode)resizeMode
|
||||
bridge:(RCTBridge *)bridge
|
||||
progressBlock:(RCTImageLoaderProgressBlock)progress
|
||||
completionBlock:(RCTImageLoaderCompletionBlock)completion;
|
||||
|
||||
|
@ -54,3 +48,17 @@ typedef void (^RCTImageLoaderCancellationBlock)(void);
|
|||
+ (BOOL)isRemoteImage:(NSString *)imageTag;
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTBridge (RCTImageLoader)
|
||||
|
||||
/**
|
||||
* The shared image loader instance
|
||||
*/
|
||||
@property (nonatomic, readonly) RCTImageLoader *imageLoader;
|
||||
|
||||
/**
|
||||
* The shared asset library instance.
|
||||
*/
|
||||
@property (nonatomic, readonly) ALAssetsLibrary *assetsLibrary;
|
||||
|
||||
@end
|
||||
|
|
|
@ -48,26 +48,21 @@ static dispatch_queue_t RCTImageLoaderQueue(void)
|
|||
}
|
||||
|
||||
@implementation RCTImageLoader
|
||||
|
||||
+ (ALAssetsLibrary *)assetsLibrary
|
||||
{
|
||||
static ALAssetsLibrary *assetsLibrary = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
assetsLibrary = [[ALAssetsLibrary alloc] init];
|
||||
});
|
||||
return assetsLibrary;
|
||||
ALAssetsLibrary *_assetsLibrary;
|
||||
}
|
||||
|
||||
+ (RCTImageLoaderCancellationBlock)loadImageWithTag:(NSString *)imageTag
|
||||
bridge:(RCTBridge *)bridge
|
||||
@synthesize bridge = _bridge;
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (RCTImageLoaderCancellationBlock)loadImageWithTag:(NSString *)imageTag
|
||||
callback:(RCTImageLoaderCompletionBlock)callback
|
||||
{
|
||||
return [self loadImageWithTag:imageTag
|
||||
size:CGSizeZero
|
||||
scale:0
|
||||
resizeMode:UIViewContentModeScaleToFill
|
||||
bridge:bridge
|
||||
progressBlock:nil
|
||||
completionBlock:callback];
|
||||
}
|
||||
|
@ -116,11 +111,18 @@ static UIImage *RCTScaledImageForAsset(ALAssetRepresentation *representation,
|
|||
return nil;
|
||||
}
|
||||
|
||||
+ (RCTImageLoaderCancellationBlock)loadImageWithTag:(NSString *)imageTag
|
||||
- (ALAssetsLibrary *)assetsLibrary
|
||||
{
|
||||
if (!_assetsLibrary) {
|
||||
_assetsLibrary = [[ALAssetsLibrary alloc] init];
|
||||
}
|
||||
return _assetsLibrary;
|
||||
}
|
||||
|
||||
- (RCTImageLoaderCancellationBlock)loadImageWithTag:(NSString *)imageTag
|
||||
size:(CGSize)size
|
||||
scale:(CGFloat)scale
|
||||
resizeMode:(UIViewContentMode)resizeMode
|
||||
bridge:(RCTBridge *)bridge
|
||||
progressBlock:(RCTImageLoaderProgressBlock)progress
|
||||
completionBlock:(RCTImageLoaderCompletionBlock)completion
|
||||
{
|
||||
|
@ -229,7 +231,7 @@ static UIImage *RCTScaledImageForAsset(ALAssetRepresentation *representation,
|
|||
}];
|
||||
}
|
||||
} else if ([imageTag hasPrefix:@"rct-image-store://"]) {
|
||||
[bridge.imageStoreManager getImageForTag:imageTag withBlock:^(UIImage *image) {
|
||||
[_bridge.imageStoreManager getImageForTag:imageTag withBlock:^(UIImage *image) {
|
||||
if (image) {
|
||||
RCTDispatchCallbackOnMainQueue(completion, nil, image);
|
||||
} else {
|
||||
|
@ -273,3 +275,17 @@ static UIImage *RCTScaledImageForAsset(ALAssetRepresentation *representation,
|
|||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTBridge (RCTImageLoader)
|
||||
|
||||
- (RCTImageLoader *)imageLoader
|
||||
{
|
||||
return self.modules[RCTBridgeModuleNameForClass([RCTImageLoader class])];
|
||||
}
|
||||
|
||||
- (ALAssetsLibrary *)assetsLibrary
|
||||
{
|
||||
return [self.imageLoader assetsLibrary];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -15,9 +15,6 @@
|
|||
#import "RCTUtils.h"
|
||||
|
||||
@implementation RCTImageRequestHandler
|
||||
{
|
||||
NSInteger _currentToken;
|
||||
}
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
|
@ -31,9 +28,10 @@ RCT_EXPORT_MODULE()
|
|||
- (id)sendRequest:(NSURLRequest *)request
|
||||
withDelegate:(id<RCTURLRequestDelegate>)delegate
|
||||
{
|
||||
NSNumber *requestToken = @(++_currentToken);
|
||||
NSString *URLString = [request.URL absoluteString];
|
||||
[RCTImageLoader loadImageWithTag:URLString bridge:_bridge callback:^(NSError *error, UIImage *image) {
|
||||
|
||||
__block RCTImageLoaderCancellationBlock requestToken = nil;
|
||||
requestToken = [_bridge.imageLoader loadImageWithTag:URLString callback:^(NSError *error, UIImage *image) {
|
||||
if (error) {
|
||||
[delegate URLRequest:requestToken didCompleteWithError:error];
|
||||
return;
|
||||
|
@ -62,4 +60,11 @@ RCT_EXPORT_MODULE()
|
|||
return requestToken;
|
||||
}
|
||||
|
||||
- (void)cancelRequest:(id /* RCTImageLoaderCancellationBlock */)requestToken
|
||||
{
|
||||
if (requestToken) {
|
||||
((RCTImageLoaderCancellationBlock)requestToken)();
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -120,13 +120,12 @@ RCT_NOT_IMPLEMENTED(-init)
|
|||
};
|
||||
}
|
||||
|
||||
[RCTImageLoader loadImageWithTag:_src
|
||||
size:self.bounds.size
|
||||
scale:RCTScreenScale()
|
||||
resizeMode:self.contentMode
|
||||
bridge:_bridge
|
||||
progressBlock:progressHandler
|
||||
completionBlock:^(NSError *error, id image) {
|
||||
[_bridge.imageLoader loadImageWithTag:_src
|
||||
size:self.bounds.size
|
||||
scale:RCTScreenScale()
|
||||
resizeMode:self.contentMode
|
||||
progressBlock:progressHandler
|
||||
completionBlock:^(NSError *error, id image) {
|
||||
|
||||
if ([image isKindOfClass:[CAAnimation class]]) {
|
||||
[self.layer addAnimation:image forKey:@"contents"];
|
||||
|
|
|
@ -20,11 +20,9 @@ var StyleSheet = require('StyleSheet');
|
|||
var UIManager = require('NativeModules').UIManager;
|
||||
var View = require('View');
|
||||
|
||||
var REACT_DEVTOOLS_HOOK: ?Object = typeof window !== 'undefined' ? window.__REACT_DEVTOOLS_GLOBAL_HOOK__ : null;
|
||||
|
||||
if (REACT_DEVTOOLS_HOOK) {
|
||||
if (window.__REACT_DEVTOOLS_GLOBAL_HOOK__) {
|
||||
// required for devtools to be able to edit react native styles
|
||||
REACT_DEVTOOLS_HOOK.resolveRNStyle = require('flattenStyle');
|
||||
window.__REACT_DEVTOOLS_GLOBAL_HOOK__.resolveRNStyle = require('flattenStyle');
|
||||
}
|
||||
|
||||
class Inspector extends React.Component {
|
||||
|
@ -43,12 +41,12 @@ class Inspector extends React.Component {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (REACT_DEVTOOLS_HOOK) {
|
||||
if (window.__REACT_DEVTOOLS_GLOBAL_HOOK__) {
|
||||
this.attachToDevtools = this.attachToDevtools.bind(this);
|
||||
REACT_DEVTOOLS_HOOK.on('react-devtools', this.attachToDevtools);
|
||||
window.__REACT_DEVTOOLS_GLOBAL_HOOK__.on('react-devtools', this.attachToDevtools);
|
||||
// if devtools is already started
|
||||
if (REACT_DEVTOOLS_HOOK.reactDevtoolsAgent) {
|
||||
this.attachToDevtools(REACT_DEVTOOLS_HOOK.reactDevtoolsAgent);
|
||||
if (window.__REACT_DEVTOOLS_GLOBAL_HOOK__.reactDevtoolsAgent) {
|
||||
this.attachToDevtools(window.__REACT_DEVTOOLS_GLOBAL_HOOK__.reactDevtoolsAgent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,8 +55,8 @@ class Inspector extends React.Component {
|
|||
if (this._subs) {
|
||||
this._subs.map(fn => fn());
|
||||
}
|
||||
if (REACT_DEVTOOLS_HOOK) {
|
||||
REACT_DEVTOOLS_HOOK.off('react-devtools', this.attachToDevtools);
|
||||
if (window.__REACT_DEVTOOLS_GLOBAL_HOOK__) {
|
||||
window.__REACT_DEVTOOLS_GLOBAL_HOOK__.off('react-devtools', this.attachToDevtools);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -85,6 +85,11 @@ function installConsoleErrorReporter() {
|
|||
return;
|
||||
}
|
||||
var str = Array.prototype.map.call(arguments, stringifySafe).join(', ');
|
||||
if (str.slice(0, 10) === '"Warning: ') {
|
||||
// React warnings use console.error so that a stack trace is shown, but
|
||||
// we don't (currently) want these to show a redbox
|
||||
return;
|
||||
}
|
||||
var error: any = new Error('console.error: ' + str);
|
||||
error.framesToPop = 1;
|
||||
reportException(error, /* isFatal */ false);
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
var define = null; // Hack to make it work with our packager
|
||||
|
||||
// Copyright 2014 Simon Lydell
|
||||
// X11 (“MIT”) Licensed. (See LICENSE.)
|
||||
// X11 ("MIT") Licensed. (See LICENSE.)
|
||||
|
||||
void (function(root, factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
|
|
|
@ -148,6 +148,7 @@
|
|||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
@ -182,6 +183,7 @@
|
|||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
|
|
@ -169,6 +169,7 @@
|
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
@ -208,6 +209,7 @@
|
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
|
|
@ -148,6 +148,7 @@
|
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
@ -188,6 +189,7 @@
|
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
|
|
@ -189,6 +189,7 @@
|
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
@ -233,6 +234,7 @@
|
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
|
|
@ -69,6 +69,11 @@ function renderApplication<D, P, S>(
|
|||
rootTag,
|
||||
'Expect to have a valid rootTag, instead got ', rootTag
|
||||
);
|
||||
// not when debugging in chrome
|
||||
if (__DEV__ && !window.document) {
|
||||
var setupDevtools = require('setupDevtools');
|
||||
setupDevtools();
|
||||
}
|
||||
React.render(
|
||||
<AppContainer rootTag={rootTag}>
|
||||
<RootComponent
|
||||
|
|
|
@ -27,19 +27,22 @@ var warning = require('warning');
|
|||
* implementations. Config information is extracted from data exported from the
|
||||
* RCTUIManager module. You should also wrap the native component in a
|
||||
* hand-written component with full propTypes definitions and other
|
||||
* documentation - pass the hand-written component in as `wrapperComponent` to
|
||||
* documentation - pass the hand-written component in as `componentInterface` to
|
||||
* verify all the native props are documented via `propTypes`.
|
||||
*
|
||||
* If some native props shouldn't be exposed in the wrapper interface, you can
|
||||
* pass null for `wrapperComponent` and call `verifyPropTypes` directly
|
||||
* pass null for `componentInterface` and call `verifyPropTypes` directly
|
||||
* with `nativePropsToIgnore`;
|
||||
*
|
||||
* Common types are lined up with the appropriate prop differs with
|
||||
* `TypeToDifferMap`. Non-scalar types not in the map default to `deepDiffer`.
|
||||
*/
|
||||
import type { ComponentInterface } from 'verifyPropTypes';
|
||||
|
||||
function requireNativeComponent(
|
||||
viewName: string,
|
||||
wrapperComponent: ?Function
|
||||
componentInterface?: ?ComponentInterface,
|
||||
extraConfig?: ?{nativeOnly?: Object},
|
||||
): Function {
|
||||
var viewConfig = RCTUIManager[viewName];
|
||||
if (!viewConfig || !viewConfig.NativeProps) {
|
||||
|
@ -52,12 +55,17 @@ function requireNativeComponent(
|
|||
};
|
||||
viewConfig.uiViewClassName = viewName;
|
||||
viewConfig.validAttributes = {};
|
||||
viewConfig.propTypes = componentInterface && componentInterface.propTypes;
|
||||
for (var key in nativeProps) {
|
||||
var differ = TypeToDifferMap[nativeProps[key]];
|
||||
viewConfig.validAttributes[key] = differ ? {diff: differ} : true;
|
||||
}
|
||||
if (__DEV__) {
|
||||
wrapperComponent && verifyPropTypes(wrapperComponent, viewConfig);
|
||||
componentInterface && verifyPropTypes(
|
||||
componentInterface,
|
||||
viewConfig,
|
||||
extraConfig && extraConfig.nativeOnly
|
||||
);
|
||||
}
|
||||
return createReactNativeComponentClass(viewConfig);
|
||||
}
|
||||
|
|
|
@ -14,16 +14,24 @@
|
|||
var ReactNativeStyleAttributes = require('ReactNativeStyleAttributes');
|
||||
var View = require('View');
|
||||
|
||||
export type ComponentInterface = ReactClass<any, any, any> | {
|
||||
name?: string;
|
||||
displayName?: string;
|
||||
propTypes: Object;
|
||||
};
|
||||
|
||||
function verifyPropTypes(
|
||||
component: Function,
|
||||
componentInterface: ComponentInterface,
|
||||
viewConfig: Object,
|
||||
nativePropsToIgnore?: Object
|
||||
nativePropsToIgnore?: ?Object
|
||||
) {
|
||||
if (!viewConfig) {
|
||||
return; // This happens for UnimplementedView.
|
||||
}
|
||||
var componentName = component.name || component.displayName;
|
||||
if (!component.propTypes) {
|
||||
var componentName = componentInterface.name ||
|
||||
componentInterface.displayName ||
|
||||
'unknown';
|
||||
if (!componentInterface.propTypes) {
|
||||
throw new Error(
|
||||
'`' + componentName + '` has no propTypes defined`'
|
||||
);
|
||||
|
@ -31,7 +39,7 @@ function verifyPropTypes(
|
|||
|
||||
var nativeProps = viewConfig.NativeProps;
|
||||
for (var prop in nativeProps) {
|
||||
if (!component.propTypes[prop] &&
|
||||
if (!componentInterface.propTypes[prop] &&
|
||||
!View.propTypes[prop] &&
|
||||
!ReactNativeStyleAttributes[prop] &&
|
||||
(!nativePropsToIgnore || !nativePropsToIgnore[prop])) {
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
var ReactChildren = require('ReactChildren');
|
||||
var ReactClass = require('ReactClass');
|
||||
var ReactComponent = require('ReactComponent');
|
||||
var ReactContext = require('ReactContext');
|
||||
var ReactCurrentOwner = require('ReactCurrentOwner');
|
||||
var ReactElement = require('ReactElement');
|
||||
var ReactElementValidator = require('ReactElementValidator');
|
||||
|
@ -27,6 +26,7 @@ var deprecated = require('deprecated');
|
|||
var findNodeHandle = require('findNodeHandle');
|
||||
var invariant = require('invariant');
|
||||
var onlyChild = require('onlyChild');
|
||||
var warning = require('warning');
|
||||
|
||||
ReactNativeDefaultInjection.inject();
|
||||
|
||||
|
@ -61,7 +61,6 @@ var augmentElement = function(element: ReactElement) {
|
|||
);
|
||||
}
|
||||
element._owner = ReactCurrentOwner.current;
|
||||
element._context = ReactContext.current;
|
||||
if (element.type.defaultProps) {
|
||||
resolveDefaultProps(element);
|
||||
}
|
||||
|
@ -103,20 +102,14 @@ var ReactNative = {
|
|||
isValidElement: ReactElement.isValidElement,
|
||||
|
||||
// Deprecations (remove for 0.13)
|
||||
renderComponent: deprecated(
|
||||
'React',
|
||||
'renderComponent',
|
||||
'render',
|
||||
this,
|
||||
render
|
||||
),
|
||||
isValidComponent: deprecated(
|
||||
'React',
|
||||
'isValidComponent',
|
||||
'isValidElement',
|
||||
this,
|
||||
ReactElement.isValidElement
|
||||
)
|
||||
renderComponent: function(
|
||||
element: ReactElement,
|
||||
mountInto: number,
|
||||
callback?: ?(() => void)
|
||||
): ?ReactComponent {
|
||||
warning('Use React.render instead of React.renderComponent');
|
||||
return ReactNative.render(element, mountInto, callback);
|
||||
},
|
||||
};
|
||||
|
||||
// Inject the runtime into a devtools global hook regardless of browser.
|
||||
|
|
|
@ -90,7 +90,7 @@ function inject() {
|
|||
ReactNativeComponent.injection.injectTextComponentClass(
|
||||
ReactNativeTextComponent
|
||||
);
|
||||
ReactNativeComponent.injection.injectAutoWrapper(function(tag) {
|
||||
ReactNativeComponent.injection.injectGenericComponentClass(function(tag) {
|
||||
// Show a nicer error message for non-function tags
|
||||
var info = '';
|
||||
if (typeof tag === 'string' && /^[a-z]/.test(tag)) {
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
var RCTUIManager = require('NativeModules').UIManager;
|
||||
|
||||
var ReactElement = require('ReactElement');
|
||||
var ReactNativeTagHandles = require('ReactNativeTagHandles');
|
||||
var ReactPerf = require('ReactPerf');
|
||||
var ReactReconciler = require('ReactReconciler');
|
||||
|
@ -27,6 +28,17 @@ function instanceNumberToChildRootID(rootNodeID, instanceNumber) {
|
|||
return rootNodeID + '[' + instanceNumber + ']';
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporary (?) hack so that we can store all top-level pending updates on
|
||||
* composites instead of having to worry about different types of components
|
||||
* here.
|
||||
*/
|
||||
var TopLevelWrapper = function() {};
|
||||
TopLevelWrapper.prototype.render = function() {
|
||||
// this.props is actually a ReactElement
|
||||
return this.props;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mounts this component and inserts it into the DOM.
|
||||
*
|
||||
|
@ -43,7 +55,7 @@ function mountComponentIntoNode(
|
|||
var markup = ReactReconciler.mountComponent(
|
||||
componentInstance, rootID, transaction, emptyObject
|
||||
);
|
||||
componentInstance._isTopLevel = true;
|
||||
componentInstance._renderedComponent._topLevelWrapper = componentInstance;
|
||||
ReactNativeMount._mountImageIntoNode(markup, container);
|
||||
}
|
||||
|
||||
|
@ -94,13 +106,22 @@ var ReactNativeMount = {
|
|||
containerTag: number,
|
||||
callback?: ?(() => void)
|
||||
): ?ReactComponent {
|
||||
var nextWrappedElement = new ReactElement(
|
||||
TopLevelWrapper,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
nextElement
|
||||
);
|
||||
|
||||
var topRootNodeID = ReactNativeTagHandles.tagToRootNodeID[containerTag];
|
||||
if (topRootNodeID) {
|
||||
var prevComponent = ReactNativeMount._instancesByContainerID[topRootNodeID];
|
||||
if (prevComponent) {
|
||||
var prevElement = prevComponent._currentElement;
|
||||
var prevWrappedElement = prevComponent._currentElement;
|
||||
var prevElement = prevWrappedElement.props;
|
||||
if (shouldUpdateReactComponent(prevElement, nextElement)) {
|
||||
ReactUpdateQueue.enqueueElementInternal(prevComponent, nextElement);
|
||||
ReactUpdateQueue.enqueueElementInternal(prevComponent, nextWrappedElement);
|
||||
if (callback) {
|
||||
ReactUpdateQueue.enqueueCallbackInternal(prevComponent, callback);
|
||||
}
|
||||
|
@ -122,7 +143,7 @@ var ReactNativeMount = {
|
|||
containerTag
|
||||
);
|
||||
|
||||
var instance = instantiateReactComponent(nextElement);
|
||||
var instance = instantiateReactComponent(nextWrappedElement);
|
||||
ReactNativeMount._instancesByContainerID[topRootNodeID] = instance;
|
||||
|
||||
var childRootNodeID = instanceNumberToChildRootID(
|
||||
|
@ -234,6 +255,10 @@ var ReactNativeMount = {
|
|||
|
||||
getNode: function<T>(id: T): T {
|
||||
return id;
|
||||
},
|
||||
|
||||
getID: function<T>(id: T): T {
|
||||
return id;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ var ReactNativeBaseComponent = require('ReactNativeBaseComponent');
|
|||
type ReactNativeBaseComponentViewConfig = {
|
||||
validAttributes: Object;
|
||||
uiViewClassName: string;
|
||||
propTypes?: Object,
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -36,6 +37,7 @@ var createReactNativeComponentClass = function(
|
|||
};
|
||||
Constructor.displayName = viewConfig.uiViewClassName;
|
||||
Constructor.viewConfig = viewConfig;
|
||||
Constructor.propTypes = viewConfig.propTypes;
|
||||
Constructor.prototype = new ReactNativeBaseComponent(viewConfig);
|
||||
Constructor.prototype.constructor = Constructor;
|
||||
|
||||
|
|
|
@ -149,6 +149,7 @@
|
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
@ -188,6 +189,7 @@
|
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
{
|
||||
NSTextStorage *_textStorage;
|
||||
NSMutableArray *_reactSubviews;
|
||||
CAShapeLayer *_highlightLayer;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
|
@ -78,8 +79,36 @@
|
|||
NSTextContainer *textContainer = [layoutManager.textContainers firstObject];
|
||||
CGRect textFrame = UIEdgeInsetsInsetRect(self.bounds, _contentInset);
|
||||
NSRange glyphRange = [layoutManager glyphRangeForTextContainer:textContainer];
|
||||
|
||||
[layoutManager drawBackgroundForGlyphRange:glyphRange atPoint:textFrame.origin];
|
||||
[layoutManager drawGlyphsForGlyphRange:glyphRange atPoint:textFrame.origin];
|
||||
|
||||
__block UIBezierPath *highlightPath = nil;
|
||||
[layoutManager.textStorage enumerateAttributesInRange:glyphRange options:0 usingBlock:^(NSDictionary *attrs, NSRange range, __unused BOOL *stop){
|
||||
if ([attrs[RCTIsHighlightedAttributeName] boolValue]) {
|
||||
[layoutManager enumerateEnclosingRectsForGlyphRange:range withinSelectedGlyphRange:range inTextContainer:textContainer usingBlock:^(CGRect r, __unused BOOL *s){
|
||||
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(r, -2, -2) cornerRadius:2];
|
||||
if (highlightPath) {
|
||||
[highlightPath appendPath:path];
|
||||
} else {
|
||||
highlightPath = path;
|
||||
}
|
||||
}];
|
||||
}
|
||||
}];
|
||||
|
||||
if (highlightPath) {
|
||||
if (!_highlightLayer) {
|
||||
_highlightLayer = [CAShapeLayer layer];
|
||||
_highlightLayer.fillColor = [UIColor colorWithWhite:0 alpha:0.25].CGColor;
|
||||
[self.layer addSublayer:_highlightLayer];
|
||||
}
|
||||
_highlightLayer.position = (CGPoint){_contentInset.left, _contentInset.top};
|
||||
_highlightLayer.path = highlightPath.CGPath;
|
||||
} else {
|
||||
[_highlightLayer removeFromSuperlayer];
|
||||
_highlightLayer = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSNumber *)reactTagAtPoint:(CGPoint)point
|
||||
|
|
|
@ -199,6 +199,7 @@
|
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
@ -238,6 +239,7 @@
|
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
|
|
@ -74,19 +74,24 @@ var Text = React.createClass({
|
|||
propTypes: {
|
||||
/**
|
||||
* Used to truncate the text with an elipsis after computing the text
|
||||
* layout, including line wrapping, such that the total number of lines does
|
||||
* not exceed this number.
|
||||
* layout, including line wrapping, such that the total number of lines
|
||||
* does not exceed this number.
|
||||
*/
|
||||
numberOfLines: React.PropTypes.number,
|
||||
/**
|
||||
* This function is called on press. Text intrinsically supports press
|
||||
* handling with a default highlight state (which can be disabled with
|
||||
* `suppressHighlighting`).
|
||||
* Invoked on mount and layout changes with
|
||||
*
|
||||
* `{nativeEvent: {layout: {x, y, width, height}}}`
|
||||
*/
|
||||
onLayout: React.PropTypes.func,
|
||||
/**
|
||||
* This function is called on press.
|
||||
*/
|
||||
onPress: React.PropTypes.func,
|
||||
/**
|
||||
* When true, no visual change is made when text is pressed down. By
|
||||
* When true, no visual change is made when text is pressed down. By
|
||||
* default, a gray oval highlights the text on press down.
|
||||
* @platform ios
|
||||
*/
|
||||
suppressHighlighting: React.PropTypes.bool,
|
||||
style: stylePropType,
|
||||
|
@ -94,12 +99,6 @@ var Text = React.createClass({
|
|||
* Used to locate this view in end-to-end tests.
|
||||
*/
|
||||
testID: React.PropTypes.string,
|
||||
/**
|
||||
* Invoked on mount and layout changes with
|
||||
*
|
||||
* {nativeEvent: {layout: {x, y, width, height}}}.
|
||||
*/
|
||||
onLayout: React.PropTypes.func,
|
||||
},
|
||||
|
||||
viewConfig: viewConfig,
|
||||
|
|
|
@ -16,30 +16,52 @@ var ViewStylePropTypes = require('ViewStylePropTypes');
|
|||
|
||||
// TODO: use spread instead of Object.assign/create after #6560135 is fixed
|
||||
var TextStylePropTypes = Object.assign(Object.create(ViewStylePropTypes), {
|
||||
color: ReactPropTypes.string,
|
||||
fontFamily: ReactPropTypes.string,
|
||||
fontSize: ReactPropTypes.number,
|
||||
fontStyle: ReactPropTypes.oneOf(['normal', 'italic']),
|
||||
/**
|
||||
* Specifies font weight. The values 'normal' and 'bold' are supported for
|
||||
* most fonts. Not all fonts have a variant for each of the numeric values,
|
||||
* in that case the closest one is chosen.
|
||||
*/
|
||||
fontWeight: ReactPropTypes.oneOf(
|
||||
['normal' /*default*/, 'bold',
|
||||
'100', '200', '300', '400', '500', '600', '700', '800', '900']
|
||||
),
|
||||
fontStyle: ReactPropTypes.oneOf(['normal', 'italic']),
|
||||
/**
|
||||
* @platform ios
|
||||
*/
|
||||
letterSpacing: ReactPropTypes.number,
|
||||
lineHeight: ReactPropTypes.number,
|
||||
color: ReactPropTypes.string,
|
||||
// NOTE: 'justify is supported only on iOS
|
||||
/**
|
||||
* Specifies text alignment. The value 'justify' is only supported on iOS.
|
||||
*/
|
||||
textAlign: ReactPropTypes.oneOf(
|
||||
['auto' /*default*/, 'left', 'right', 'center', 'justify']
|
||||
),
|
||||
/**
|
||||
* @platform ios
|
||||
*/
|
||||
textDecorationLine: ReactPropTypes.oneOf(
|
||||
['none' /*default*/, 'underline', 'line-through', 'underline line-through']
|
||||
),
|
||||
/**
|
||||
* @platform ios
|
||||
*/
|
||||
textDecorationStyle: ReactPropTypes.oneOf(
|
||||
['solid' /*default*/, 'double', 'dotted','dashed']
|
||||
),
|
||||
/**
|
||||
* @platform ios
|
||||
*/
|
||||
textDecorationColor: ReactPropTypes.string,
|
||||
/**
|
||||
* @platform ios
|
||||
*/
|
||||
writingDirection: ReactPropTypes.oneOf(
|
||||
['auto' /*default*/, 'ltr', 'rtl']
|
||||
),
|
||||
letterSpacing: ReactPropTypes.number,
|
||||
textDecorationLine:ReactPropTypes.oneOf(
|
||||
['none' /*default*/, 'underline', 'line-through', 'underline line-through']
|
||||
),
|
||||
textDecorationStyle:ReactPropTypes.oneOf(
|
||||
['solid' /*default*/, 'double', 'dotted','dashed']
|
||||
),
|
||||
textDecorationColor: ReactPropTypes.string,
|
||||
});
|
||||
|
||||
// Text doesn't support padding correctly (#4841912)
|
||||
|
|
|
@ -151,6 +151,7 @@
|
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
@ -195,6 +196,7 @@
|
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
|
|
@ -152,6 +152,7 @@
|
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
@ -193,6 +194,7 @@
|
|||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#import "RCTJavaScriptLoader.h"
|
||||
#import "RCTLog.h"
|
||||
#import "RCTModuleData.h"
|
||||
#import "RCTModuleMap.h"
|
||||
#import "RCTModuleMethod.h"
|
||||
#import "RCTPerformanceLogger.h"
|
||||
#import "RCTPerfStats.h"
|
||||
|
@ -62,8 +63,8 @@ id<RCTJavaScriptExecutor> RCTGetLatestExecutor(void)
|
|||
{
|
||||
BOOL _loading;
|
||||
__weak id<RCTJavaScriptExecutor> _javaScriptExecutor;
|
||||
NSMutableArray *_modules;
|
||||
NSDictionary *_modulesByName;
|
||||
NSMutableArray *_moduleDataByID;
|
||||
RCTModuleMap *_modulesByName;
|
||||
CADisplayLink *_mainDisplayLink;
|
||||
CADisplayLink *_jsDisplayLink;
|
||||
NSMutableSet *_frameUpdateObservers;
|
||||
|
@ -89,7 +90,7 @@ id<RCTJavaScriptExecutor> RCTGetLatestExecutor(void)
|
|||
*/
|
||||
_valid = YES;
|
||||
_loading = YES;
|
||||
_modules = [[NSMutableArray alloc] init];
|
||||
_moduleDataByID = [[NSMutableArray alloc] init];
|
||||
_frameUpdateObservers = [[NSMutableSet alloc] init];
|
||||
_scheduledCalls = [[NSMutableArray alloc] init];
|
||||
_scheduledCallbacks = [[RCTSparseArray alloc] init];
|
||||
|
@ -166,7 +167,7 @@ RCT_NOT_IMPLEMENTED(-initWithBundleURL:(__unused NSURL *)bundleURL
|
|||
}
|
||||
|
||||
// Instantiate modules
|
||||
_modules = [[NSMutableArray alloc] init];
|
||||
_moduleDataByID = [[NSMutableArray alloc] init];
|
||||
NSMutableDictionary *modulesByName = [preregisteredModules mutableCopy];
|
||||
for (Class moduleClass in RCTGetModuleClasses()) {
|
||||
NSString *moduleName = RCTBridgeModuleNameForClass(moduleClass);
|
||||
|
@ -199,7 +200,7 @@ RCT_NOT_IMPLEMENTED(-initWithBundleURL:(__unused NSURL *)bundleURL
|
|||
}
|
||||
|
||||
// Store modules
|
||||
_modulesByName = [modulesByName copy];
|
||||
_modulesByName = [[RCTModuleMap alloc] initWithDictionary:modulesByName];
|
||||
|
||||
/**
|
||||
* The executor is a bridge module, wait for it to be created and set it before
|
||||
|
@ -217,9 +218,9 @@ RCT_NOT_IMPLEMENTED(-initWithBundleURL:(__unused NSURL *)bundleURL
|
|||
}
|
||||
|
||||
RCTModuleData *moduleData = [[RCTModuleData alloc] initWithExecutor:_javaScriptExecutor
|
||||
uid:@(_modules.count)
|
||||
uid:@(_moduleDataByID.count)
|
||||
instance:module];
|
||||
[_modules addObject:moduleData];
|
||||
[_moduleDataByID addObject:moduleData];
|
||||
|
||||
if ([module conformsToProtocol:@protocol(RCTFrameUpdateObserver)]) {
|
||||
[_frameUpdateObservers addObject:moduleData];
|
||||
|
@ -236,7 +237,7 @@ RCT_NOT_IMPLEMENTED(-initWithBundleURL:(__unused NSURL *)bundleURL
|
|||
|
||||
// Inject module data into JS context
|
||||
NSMutableDictionary *config = [[NSMutableDictionary alloc] init];
|
||||
for (RCTModuleData *moduleData in _modules) {
|
||||
for (RCTModuleData *moduleData in _moduleDataByID) {
|
||||
config[moduleData.name] = moduleData.config;
|
||||
}
|
||||
NSString *configJSON = RCTJSONStringify(@{
|
||||
|
@ -275,14 +276,21 @@ RCT_NOT_IMPLEMENTED(-initWithBundleURL:(__unused NSURL *)bundleURL
|
|||
RCTJavaScriptLoader *loader = [[RCTJavaScriptLoader alloc] initWithBridge:self];
|
||||
[loader loadBundleAtURL:bundleURL onComplete:^(NSError *error, NSString *script) {
|
||||
RCTPerformanceLoggerEnd(RCTPLScriptDownload);
|
||||
RCTProfileEndEvent(@"JavaScript dowload", @"init,download", @[]);
|
||||
RCTProfileEndEvent(@"JavaScript download", @"init,download", @[]);
|
||||
|
||||
_loading = NO;
|
||||
if (!self.isValid) {
|
||||
return;
|
||||
}
|
||||
|
||||
[[RCTRedBox sharedInstance] dismiss];
|
||||
static BOOL shouldDismiss = NO;
|
||||
if (shouldDismiss) {
|
||||
[[RCTRedBox sharedInstance] dismiss];
|
||||
}
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
shouldDismiss = YES;
|
||||
});
|
||||
|
||||
RCTSourceCode *sourceCodeModule = self.modules[RCTBridgeModuleNameForClass([RCTSourceCode class])];
|
||||
sourceCodeModule.scriptURL = bundleURL;
|
||||
|
@ -356,7 +364,7 @@ RCT_NOT_IMPLEMENTED(-initWithBundleURL:(__unused NSURL *)bundleURL
|
|||
|
||||
// Invalidate modules
|
||||
dispatch_group_t group = dispatch_group_create();
|
||||
for (RCTModuleData *moduleData in _modules) {
|
||||
for (RCTModuleData *moduleData in _moduleDataByID) {
|
||||
if (moduleData.instance == _javaScriptExecutor) {
|
||||
continue;
|
||||
}
|
||||
|
@ -380,7 +388,7 @@ RCT_NOT_IMPLEMENTED(-initWithBundleURL:(__unused NSURL *)bundleURL
|
|||
if (RCTProfileIsProfiling()) {
|
||||
RCTProfileUnhookModules(self);
|
||||
}
|
||||
_modules = nil;
|
||||
_moduleDataByID = nil;
|
||||
_modulesByName = nil;
|
||||
_frameUpdateObservers = nil;
|
||||
|
||||
|
@ -561,9 +569,15 @@ RCT_NOT_IMPLEMENTED(-initWithBundleURL:(__unused NSURL *)bundleURL
|
|||
return;
|
||||
}
|
||||
|
||||
NSMapTable *buckets = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsStrongMemory valueOptions:NSPointerFunctionsStrongMemory capacity:_modules.count];
|
||||
NSMapTable *buckets = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsStrongMemory
|
||||
valueOptions:NSPointerFunctionsStrongMemory
|
||||
capacity:_moduleDataByID.count];
|
||||
for (NSUInteger i = 0; i < numRequests; i++) {
|
||||
RCTModuleData *moduleData = _modules[[moduleIDs[i] integerValue]];
|
||||
RCTModuleData *moduleData = _moduleDataByID[[moduleIDs[i] integerValue]];
|
||||
if (RCT_DEBUG) {
|
||||
// verify that class has been registered
|
||||
(void)_modulesByName[moduleData.name];
|
||||
}
|
||||
NSMutableOrderedSet *set = [buckets objectForKey:moduleData];
|
||||
if (!set) {
|
||||
set = [[NSMutableOrderedSet alloc] init];
|
||||
|
@ -589,12 +603,13 @@ RCT_NOT_IMPLEMENTED(-initWithBundleURL:(__unused NSURL *)bundleURL
|
|||
params:paramsArrays[index]];
|
||||
}
|
||||
}
|
||||
RCTProfileEndEvent(RCTCurrentThreadName(), @"objc_call,dispatch_async", @{ @"calls": @(calls.count) });
|
||||
|
||||
RCTProfileEndEvent(RCTCurrentThreadName(), @"objc_call,dispatch_async", @{ @"calls": @(calls.count) });
|
||||
}];
|
||||
}
|
||||
|
||||
// TODO: batchDidComplete is only used by RCTUIManager - can we eliminate this special case?
|
||||
for (RCTModuleData *moduleData in _modules) {
|
||||
for (RCTModuleData *moduleData in _moduleDataByID) {
|
||||
if ([moduleData.instance respondsToSelector:@selector(batchDidComplete)]) {
|
||||
[moduleData dispatchBlock:^{
|
||||
[moduleData.instance batchDidComplete];
|
||||
|
@ -617,10 +632,9 @@ RCT_NOT_IMPLEMENTED(-initWithBundleURL:(__unused NSURL *)bundleURL
|
|||
return NO;
|
||||
}
|
||||
|
||||
|
||||
RCTProfileBeginEvent();
|
||||
|
||||
RCTModuleData *moduleData = _modules[moduleID];
|
||||
RCTModuleData *moduleData = _moduleDataByID[moduleID];
|
||||
if (RCT_DEBUG && !moduleData) {
|
||||
RCTLogError(@"No module found for id '%zd'", moduleID);
|
||||
return NO;
|
||||
|
|
|
@ -80,6 +80,14 @@ NSString *RCTBridgeModuleNameForClass(Class cls)
|
|||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if class has been registered
|
||||
*/
|
||||
BOOL RCTBridgeModuleClassIsRegistered(Class);
|
||||
BOOL RCTBridgeModuleClassIsRegistered(Class cls)
|
||||
{
|
||||
return [objc_getAssociatedObject(cls, &RCTBridgeModuleClassIsRegistered) ?: @YES boolValue];
|
||||
}
|
||||
|
||||
@implementation RCTBridge
|
||||
|
||||
|
@ -108,8 +116,12 @@ dispatch_queue_t RCTJSThread;
|
|||
if (class_conformsToProtocol(superclass, @protocol(RCTBridgeModule)))
|
||||
{
|
||||
if (![RCTModuleClasses containsObject:cls]) {
|
||||
RCTLogError(@"Class %@ was not exported. Did you forget to use "
|
||||
"RCT_EXPORT_MODULE()?", NSStringFromClass(cls));
|
||||
RCTLogWarn(@"Class %@ was not exported. Did you forget to use "
|
||||
"RCT_EXPORT_MODULE()?", cls);
|
||||
|
||||
RCTRegisterModule(cls);
|
||||
objc_setAssociatedObject(cls, &RCTBridgeModuleClassIsRegistered,
|
||||
@NO, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -254,5 +266,4 @@ RCT_NOT_IMPLEMENTED(-init)
|
|||
RCT_INNER_BRIDGE_ONLY(_invokeAndProcessModule:(__unused NSString *)module
|
||||
method:(__unused NSString *)method
|
||||
arguments:(__unused NSArray *)args);
|
||||
|
||||
@end
|
||||
|
|
|
@ -1075,24 +1075,64 @@ BOOL RCTSetProperty(id target, NSString *keyPath, SEL type, id json)
|
|||
}
|
||||
|
||||
@try {
|
||||
// Get converted value
|
||||
|
||||
NSMethodSignature *signature = [RCTConvert methodSignatureForSelector:type];
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
|
||||
[invocation setArgument:&type atIndex:1];
|
||||
[invocation setArgument:&json atIndex:2];
|
||||
[invocation invokeWithTarget:[RCTConvert class]];
|
||||
NSUInteger length = [signature methodReturnLength];
|
||||
void *value = malloc(length);
|
||||
[invocation getReturnValue:value];
|
||||
switch (signature.methodReturnType[0]) {
|
||||
|
||||
// Set converted value
|
||||
signature = [target methodSignatureForSelector:setter];
|
||||
invocation = [NSInvocation invocationWithMethodSignature:signature];
|
||||
[invocation setArgument:&setter atIndex:1];
|
||||
[invocation setArgument:value atIndex:2];
|
||||
[invocation invokeWithTarget:target];
|
||||
free(value);
|
||||
#define RCT_SET_CASE(_value, _type) \
|
||||
case _value: { \
|
||||
_type (*convert)(id, SEL, id) = (typeof(convert))objc_msgSend; \
|
||||
void (*set)(id, SEL, _type) = (typeof(set))objc_msgSend; \
|
||||
set(target, setter, convert([RCTConvert class], type, json)); \
|
||||
break; \
|
||||
}
|
||||
|
||||
RCT_SET_CASE(':', SEL)
|
||||
RCT_SET_CASE('*', const char *)
|
||||
RCT_SET_CASE('c', char)
|
||||
RCT_SET_CASE('C', unsigned char)
|
||||
RCT_SET_CASE('s', short)
|
||||
RCT_SET_CASE('S', unsigned short)
|
||||
RCT_SET_CASE('i', int)
|
||||
RCT_SET_CASE('I', unsigned int)
|
||||
RCT_SET_CASE('l', long)
|
||||
RCT_SET_CASE('L', unsigned long)
|
||||
RCT_SET_CASE('q', long long)
|
||||
RCT_SET_CASE('Q', unsigned long long)
|
||||
RCT_SET_CASE('f', float)
|
||||
RCT_SET_CASE('d', double)
|
||||
RCT_SET_CASE('B', BOOL)
|
||||
RCT_SET_CASE('^', void *)
|
||||
|
||||
case '@': {
|
||||
id (*convert)(id, SEL, id) = (typeof(convert))objc_msgSend;
|
||||
void (*set)(id, SEL, id) = (typeof(set))objc_msgSend;
|
||||
set(target, setter, convert([RCTConvert class], type, json));
|
||||
break;
|
||||
}
|
||||
case '{':
|
||||
default: {
|
||||
|
||||
// Get converted value
|
||||
void *value = malloc(signature.methodReturnLength);
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
|
||||
[invocation setTarget:[RCTConvert class]];
|
||||
[invocation setSelector:type];
|
||||
[invocation setArgument:&json atIndex:2];
|
||||
[invocation invoke];
|
||||
[invocation getReturnValue:value];
|
||||
|
||||
// Set converted value
|
||||
signature = [target methodSignatureForSelector:setter];
|
||||
invocation = [NSInvocation invocationWithMethodSignature:signature];
|
||||
[invocation setArgument:&setter atIndex:1];
|
||||
[invocation setArgument:value atIndex:2];
|
||||
[invocation invokeWithTarget:target];
|
||||
free(value);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
|
@ -1128,22 +1168,60 @@ BOOL RCTCopyProperty(id target, id source, NSString *keyPath)
|
|||
return NO;
|
||||
}
|
||||
|
||||
// Get value
|
||||
NSMethodSignature *signature = [source methodSignatureForSelector:getter];
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
|
||||
[invocation setArgument:&getter atIndex:1];
|
||||
[invocation invokeWithTarget:source];
|
||||
NSUInteger length = [signature methodReturnLength];
|
||||
void *value = malloc(length);
|
||||
[invocation getReturnValue:value];
|
||||
switch (signature.methodReturnType[0]) {
|
||||
|
||||
// Set value
|
||||
signature = [target methodSignatureForSelector:setter];
|
||||
invocation = [NSInvocation invocationWithMethodSignature:signature];
|
||||
[invocation setArgument:&setter atIndex:1];
|
||||
[invocation setArgument:value atIndex:2];
|
||||
[invocation invokeWithTarget:target];
|
||||
free(value);
|
||||
#define RCT_COPY_CASE(_value, _type) \
|
||||
case _value: { \
|
||||
_type (*get)(id, SEL) = (typeof(get))objc_msgSend; \
|
||||
void (*set)(id, SEL, _type) = (typeof(set))objc_msgSend; \
|
||||
set(target, setter, get(source, getter)); \
|
||||
break; \
|
||||
}
|
||||
|
||||
RCT_COPY_CASE(':', SEL)
|
||||
RCT_COPY_CASE('*', const char *)
|
||||
RCT_COPY_CASE('c', char)
|
||||
RCT_COPY_CASE('C', unsigned char)
|
||||
RCT_COPY_CASE('s', short)
|
||||
RCT_COPY_CASE('S', unsigned short)
|
||||
RCT_COPY_CASE('i', int)
|
||||
RCT_COPY_CASE('I', unsigned int)
|
||||
RCT_COPY_CASE('l', long)
|
||||
RCT_COPY_CASE('L', unsigned long)
|
||||
RCT_COPY_CASE('q', long long)
|
||||
RCT_COPY_CASE('Q', unsigned long long)
|
||||
RCT_COPY_CASE('f', float)
|
||||
RCT_COPY_CASE('d', double)
|
||||
RCT_COPY_CASE('B', BOOL)
|
||||
RCT_COPY_CASE('^', void *)
|
||||
|
||||
case '@': {
|
||||
id (*get)(id, SEL) = (typeof(get))objc_msgSend;
|
||||
void (*set)(id, SEL, id) = (typeof(set))objc_msgSend;
|
||||
set(target, setter, get(source, getter));
|
||||
break;
|
||||
}
|
||||
case '{':
|
||||
default: {
|
||||
|
||||
// Get value
|
||||
void *value = malloc(signature.methodReturnLength);
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
|
||||
[invocation setArgument:&getter atIndex:1];
|
||||
[invocation invokeWithTarget:source];
|
||||
[invocation getReturnValue:value];
|
||||
|
||||
// Set value
|
||||
signature = [target methodSignatureForSelector:setter];
|
||||
invocation = [NSInvocation invocationWithMethodSignature:signature];
|
||||
[invocation setArgument:&setter atIndex:1];
|
||||
[invocation setArgument:value atIndex:2];
|
||||
[invocation invokeWithTarget:target];
|
||||
free(value);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
@property (nonatomic, strong, readonly) NSNumber *uid;
|
||||
@property (nonatomic, strong, readonly) id<RCTBridgeModule> instance;
|
||||
|
||||
@property (nonatomic, strong, readonly) Class cls;
|
||||
@property (nonatomic, strong, readonly) Class moduleClass;
|
||||
@property (nonatomic, copy, readonly) NSString *name;
|
||||
@property (nonatomic, copy, readonly) NSArray *methods;
|
||||
@property (nonatomic, copy, readonly) NSDictionary *config;
|
||||
|
@ -28,7 +28,6 @@
|
|||
uid:(NSNumber *)uid
|
||||
instance:(id<RCTBridgeModule>)instance NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
|
||||
- (void)dispatchBlock:(dispatch_block_t)block;
|
||||
- (void)dispatchBlock:(dispatch_block_t)block dispatchGroup:(dispatch_group_t)group;
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
_javaScriptExecutor = javaScriptExecutor;
|
||||
_uid = uid;
|
||||
_instance = instance;
|
||||
_cls = [instance class];
|
||||
_name = RCTBridgeModuleNameForClass(_cls);
|
||||
_moduleClass = [instance class];
|
||||
_name = RCTBridgeModuleNameForClass(_moduleClass);
|
||||
|
||||
[self loadMethods];
|
||||
[self generateConfig];
|
||||
|
@ -39,18 +39,18 @@ RCT_NOT_IMPLEMENTED(-init);
|
|||
{
|
||||
NSMutableArray *moduleMethods = [[NSMutableArray alloc] init];
|
||||
unsigned int methodCount;
|
||||
Method *methods = class_copyMethodList(object_getClass(_cls), &methodCount);
|
||||
Method *methods = class_copyMethodList(object_getClass(_moduleClass), &methodCount);
|
||||
|
||||
for (unsigned int i = 0; i < methodCount; i++) {
|
||||
Method method = methods[i];
|
||||
SEL selector = method_getName(method);
|
||||
if ([NSStringFromSelector(selector) hasPrefix:@"__rct_export__"]) {
|
||||
IMP imp = method_getImplementation(method);
|
||||
NSArray *entries = ((NSArray *(*)(id, SEL))imp)(_cls, selector);
|
||||
NSArray *entries = ((NSArray *(*)(id, SEL))imp)(_moduleClass, selector);
|
||||
RCTModuleMethod *moduleMethod =
|
||||
[[RCTModuleMethod alloc] initWithObjCMethodName:entries[1]
|
||||
JSMethodName:entries[0]
|
||||
moduleClass:_cls];
|
||||
moduleClass:_moduleClass];
|
||||
|
||||
[moduleMethods addObject:moduleMethod];
|
||||
}
|
||||
|
|
|
@ -7,11 +7,10 @@
|
|||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import <Accelerate/Accelerate.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "RCTBridgeModule.h"
|
||||
@interface RCTModuleMap : NSDictionary
|
||||
|
||||
@interface RCTAnimationExperimentalManager : NSObject <RCTBridgeModule>
|
||||
- (instancetype)initWithDictionary:(NSDictionary *)modulesByName NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@end
|
|
@ -0,0 +1,79 @@
|
|||
/**
|
||||
* 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 "RCTModuleMap.h"
|
||||
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTBridgeModule.h"
|
||||
#import "RCTDefines.h"
|
||||
#import "RCTLog.h"
|
||||
|
||||
@implementation RCTModuleMap
|
||||
{
|
||||
NSDictionary *_modulesByName;
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(-init)
|
||||
RCT_NOT_IMPLEMENTED(-initWithCoder:aDecoder)
|
||||
RCT_NOT_IMPLEMENTED(-initWithObjects:(const id [])objects
|
||||
forKeys:(const id<NSCopying> [])keys
|
||||
count:(NSUInteger)cnt)
|
||||
|
||||
- (instancetype)initWithDictionary:(NSDictionary *)modulesByName
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_modulesByName = [modulesByName copy];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSUInteger)count
|
||||
{
|
||||
return _modulesByName.count;
|
||||
}
|
||||
|
||||
//declared in RCTBridge.m
|
||||
extern BOOL RCTBridgeModuleClassIsRegistered(Class cls);
|
||||
|
||||
- (id)objectForKey:(NSString *)moduleName
|
||||
{
|
||||
id<RCTBridgeModule> module = _modulesByName[moduleName];
|
||||
if (RCT_DEBUG) {
|
||||
if (module) {
|
||||
Class moduleClass = [module class];
|
||||
if (!RCTBridgeModuleClassIsRegistered(moduleClass)) {
|
||||
RCTLogError(@"Class %@ was not exported. Did you forget to use "
|
||||
"RCT_EXPORT_MODULE()?", moduleClass);
|
||||
}
|
||||
} else {
|
||||
Class moduleClass = NSClassFromString(moduleName);
|
||||
module = _modulesByName[moduleName];
|
||||
if (module) {
|
||||
RCTLogError(@"bridge.modules[name] expects a module name, not a class "
|
||||
"name. Did you mean to pass '%@' instead?",
|
||||
RCTBridgeModuleNameForClass(moduleClass));
|
||||
}
|
||||
}
|
||||
}
|
||||
return module;
|
||||
}
|
||||
|
||||
- (NSEnumerator *)keyEnumerator
|
||||
{
|
||||
return [_modulesByName keyEnumerator];
|
||||
}
|
||||
|
||||
- (NSArray *)allValues
|
||||
{
|
||||
// don't perform validation in this case because we only want to error when
|
||||
// an invalid module is specifically requested
|
||||
return _modulesByName.allValues;
|
||||
}
|
||||
|
||||
@end
|
|
@ -91,7 +91,7 @@ RCT_NOT_IMPLEMENTED(-init)
|
|||
[argumentBlocks addObject:^(__unused RCTBridge *bridge, NSInvocation *invocation, NSUInteger index, id json) { \
|
||||
_logic \
|
||||
[invocation setArgument:&value atIndex:index]; \
|
||||
}]; \
|
||||
}];
|
||||
|
||||
void (^addBlockArgument)(void) = ^{
|
||||
RCT_ARG_BLOCK(
|
||||
|
|
|
@ -118,19 +118,17 @@ static void RCTProfileForwardInvocation(NSObject *self, __unused SEL cmd, NSInvo
|
|||
NSString *name = [NSString stringWithFormat:@"-[%@ %@]", NSStringFromClass([self class]), NSStringFromSelector(invocation.selector)];
|
||||
SEL newSel = RCTProfileProxySelector(invocation.selector);
|
||||
|
||||
RCTProfileLock(
|
||||
if ([object_getClass(self) instancesRespondToSelector:newSel]) {
|
||||
invocation.selector = newSel;
|
||||
RCTProfileBeginEvent();
|
||||
[invocation invoke];
|
||||
RCTProfileEndEvent(name, @"objc_call,modules,auto", nil);
|
||||
} else if ([self respondsToSelector:invocation.selector]) {
|
||||
[invocation invoke];
|
||||
} else {
|
||||
// Use original selector to don't change error message
|
||||
[self doesNotRecognizeSelector:invocation.selector];
|
||||
}
|
||||
);
|
||||
if ([object_getClass(self) instancesRespondToSelector:newSel]) {
|
||||
invocation.selector = newSel;
|
||||
RCTProfileBeginEvent();
|
||||
[invocation invoke];
|
||||
RCTProfileEndEvent(name, @"objc_call,modules,auto", nil);
|
||||
} else if ([self respondsToSelector:invocation.selector]) {
|
||||
[invocation invoke];
|
||||
} else {
|
||||
// Use original selector to don't change error message
|
||||
[self doesNotRecognizeSelector:invocation.selector];
|
||||
}
|
||||
}
|
||||
|
||||
static IMP RCTProfileMsgForward(NSObject *, SEL);
|
||||
|
@ -150,7 +148,7 @@ void RCTProfileHookModules(RCTBridge *bridge)
|
|||
{
|
||||
for (RCTModuleData *moduleData in [bridge valueForKey:@"_modules"]) {
|
||||
[moduleData dispatchBlock:^{
|
||||
Class moduleClass = moduleData.cls;
|
||||
Class moduleClass = moduleData.moduleClass;
|
||||
Class proxyClass = objc_allocateClassPair(moduleClass, RCTProfileProxyClassName(moduleClass), 0);
|
||||
|
||||
if (!proxyClass) {
|
||||
|
@ -192,15 +190,13 @@ void RCTProfileHookModules(RCTBridge *bridge)
|
|||
|
||||
void RCTProfileUnhookModules(RCTBridge *bridge)
|
||||
{
|
||||
RCTProfileLock(
|
||||
for (RCTModuleData *moduleData in [bridge valueForKey:@"_modules"]) {
|
||||
Class proxyClass = object_getClass(moduleData.instance);
|
||||
if (moduleData.cls != proxyClass) {
|
||||
object_setClass(moduleData.instance, moduleData.cls);
|
||||
objc_disposeClassPair(proxyClass);
|
||||
}
|
||||
};
|
||||
);
|
||||
for (RCTModuleData *moduleData in [bridge valueForKey:@"_modules"]) {
|
||||
Class proxyClass = object_getClass(moduleData.instance);
|
||||
if (moduleData.moduleClass != proxyClass) {
|
||||
object_setClass(moduleData.instance, moduleData.moduleClass);
|
||||
objc_disposeClassPair(proxyClass);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -169,8 +169,7 @@ RCT_NOT_IMPLEMENTED(-initWithCoder:(NSCoder *)aDecoder)
|
|||
}
|
||||
|
||||
[_contentView removeFromSuperview];
|
||||
_contentView = [[RCTRootContentView alloc] initWithFrame:self.bounds
|
||||
bridge:bridge];
|
||||
_contentView = [[RCTRootContentView alloc] initWithFrame:self.bounds bridge:bridge];
|
||||
_contentView.backgroundColor = self.backgroundColor;
|
||||
[self insertSubview:_contentView atIndex:0];
|
||||
|
||||
|
|
|
@ -386,7 +386,7 @@ NSData *RCTGzipData(NSData *input, float level)
|
|||
return input;
|
||||
}
|
||||
|
||||
void *libz = dlopen("libz.dylib", RTLD_NOW);
|
||||
void *libz = dlopen("/usr/lib/libz.dylib", RTLD_LAZY);
|
||||
int (*deflateInit2_)(z_streamp, int, int, int, int, int, const char *, int) = dlsym(libz, "deflateInit2_");
|
||||
int (*deflate)(z_streamp, int) = dlsym(libz, "deflate");
|
||||
int (*deflateEnd)(z_streamp) = dlsym(libz, "deflateEnd");
|
||||
|
|
|
@ -71,4 +71,9 @@ RCT_EXPORT_METHOD(setHidden:(BOOL)hidden
|
|||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setNetworkActivityIndicatorVisible:(BOOL)visible)
|
||||
{
|
||||
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:visible];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
137327E81AA5CF210034F82E /* RCTTabBarItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 137327E21AA5CF210034F82E /* RCTTabBarItem.m */; };
|
||||
137327E91AA5CF210034F82E /* RCTTabBarItemManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 137327E41AA5CF210034F82E /* RCTTabBarItemManager.m */; };
|
||||
137327EA1AA5CF210034F82E /* RCTTabBarManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 137327E61AA5CF210034F82E /* RCTTabBarManager.m */; };
|
||||
1385D0341B665AAE000A309B /* RCTModuleMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 1385D0331B665AAE000A309B /* RCTModuleMap.m */; };
|
||||
138D6A141B53CD290074A87E /* RCTCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 138D6A131B53CD290074A87E /* RCTCache.m */; };
|
||||
13A1F71E1A75392D00D3D453 /* RCTKeyCommands.m in Sources */ = {isa = PBXBuildFile; fileRef = 13A1F71D1A75392D00D3D453 /* RCTKeyCommands.m */; };
|
||||
13AF20451AE707F9005F5298 /* RCTSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = 13AF20441AE707F9005F5298 /* RCTSlider.m */; };
|
||||
|
@ -125,6 +126,8 @@
|
|||
137327E41AA5CF210034F82E /* RCTTabBarItemManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTabBarItemManager.m; sourceTree = "<group>"; };
|
||||
137327E51AA5CF210034F82E /* RCTTabBarManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTabBarManager.h; sourceTree = "<group>"; };
|
||||
137327E61AA5CF210034F82E /* RCTTabBarManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTabBarManager.m; sourceTree = "<group>"; };
|
||||
1385D0331B665AAE000A309B /* RCTModuleMap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTModuleMap.m; sourceTree = "<group>"; };
|
||||
1385D0351B6661DB000A309B /* RCTModuleMap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTModuleMap.h; sourceTree = "<group>"; };
|
||||
138D6A121B53CD290074A87E /* RCTCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTCache.h; sourceTree = "<group>"; };
|
||||
138D6A131B53CD290074A87E /* RCTCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTCache.m; sourceTree = "<group>"; };
|
||||
13A1F71C1A75392D00D3D453 /* RCTKeyCommands.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTKeyCommands.h; sourceTree = "<group>"; };
|
||||
|
@ -437,6 +440,8 @@
|
|||
83CBBA4E1A601E3B00E9B192 /* RCTLog.m */,
|
||||
14C2CA721B3AC64300E6CBB2 /* RCTModuleData.h */,
|
||||
14C2CA731B3AC64300E6CBB2 /* RCTModuleData.m */,
|
||||
1385D0351B6661DB000A309B /* RCTModuleMap.h */,
|
||||
1385D0331B665AAE000A309B /* RCTModuleMap.m */,
|
||||
14C2CA6F1B3AC63800E6CBB2 /* RCTModuleMethod.h */,
|
||||
14C2CA701B3AC63800E6CBB2 /* RCTModuleMethod.m */,
|
||||
142014181B32094000CC17BA /* RCTPerformanceLogger.h */,
|
||||
|
@ -612,6 +617,7 @@
|
|||
14435CE51AAC4AE100FC20F4 /* RCTMap.m in Sources */,
|
||||
134FCB3E1A6E7F0800051CC8 /* RCTWebViewExecutor.m in Sources */,
|
||||
13B0801C1A69489C00A75B9A /* RCTNavItem.m in Sources */,
|
||||
1385D0341B665AAE000A309B /* RCTModuleMap.m in Sources */,
|
||||
1403F2B31B0AE60700C2A9A4 /* RCTPerfStats.m in Sources */,
|
||||
83CBBA691A601EF300E9B192 /* RCTEventDispatcher.m in Sources */,
|
||||
13E0674A1A70F434002CDEE1 /* RCTUIManager.m in Sources */,
|
||||
|
@ -654,8 +660,10 @@
|
|||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
@ -695,8 +703,10 @@
|
|||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "";
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
|
||||
GCC_WARN_SHADOW = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
"optimist": "0.6.1",
|
||||
"promise": "^7.0.3",
|
||||
"react-timer-mixin": "^0.13.1",
|
||||
"react-tools": "0.13.2",
|
||||
"react-tools": "git://github.com/facebook/react#b4e74e38e43ac53af8acd62c78c9213be0194245",
|
||||
"rebound": "^0.0.12",
|
||||
"sane": "^1.1.2",
|
||||
"semver": "^4.3.6",
|
||||
|
@ -71,7 +71,7 @@
|
|||
"underscore": "1.7.0",
|
||||
"wordwrap": "^1.0.0",
|
||||
"worker-farm": "^1.3.1",
|
||||
"ws": "0.4.31",
|
||||
"ws": "^0.7.2",
|
||||
"yargs": "1.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -14,9 +14,13 @@ var path = require('path');
|
|||
// modulePathIgnorePatterns.
|
||||
var sharedBlacklist = [
|
||||
'website',
|
||||
'node_modules/react-tools/src/utils/ImmutableObject.js',
|
||||
'node_modules/react-tools/src/core/ReactInstanceHandles.js',
|
||||
'node_modules/react-tools/src/event/EventPropagators.js'
|
||||
'node_modules/react-tools/src/React.js',
|
||||
'node_modules/react-tools/src/renderers/shared/event/EventPropagators.js',
|
||||
'node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderEventPlugin.js',
|
||||
'node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderSyntheticEvent.js',
|
||||
'node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderTouchHistoryStore.js',
|
||||
'node_modules/react-tools/src/renderers/shared/reconciler/ReactInstanceHandles.js',
|
||||
'node_modules/react-tools/src/shared/vendor/core/ExecutionEnvironment.js',
|
||||
];
|
||||
|
||||
var platformBlacklists = {
|
||||
|
@ -24,17 +28,10 @@ var platformBlacklists = {
|
|||
'.ios.js'
|
||||
],
|
||||
ios: [
|
||||
'node_modules/react-tools/src/browser/ui/React.js',
|
||||
'node_modules/react-tools/src/browser/eventPlugins/ResponderEventPlugin.js',
|
||||
'node_modules/react-tools/src/vendor/core/ExecutionEnvironment.js',
|
||||
'.web.js',
|
||||
'.android.js',
|
||||
],
|
||||
android: [
|
||||
'node_modules/react-tools/src/browser/ui/React.js',
|
||||
'node_modules/react-tools/src/browser/eventPlugins/ResponderEventPlugin.js',
|
||||
'node_modules/react-tools/src/browser/ReactTextComponent.js',
|
||||
'node_modules/react-tools/src/vendor/core/ExecutionEnvironment.js',
|
||||
'.web.js',
|
||||
'.ios.js',
|
||||
],
|
||||
|
|
|
@ -39,6 +39,7 @@ describe('processRequest', function() {
|
|||
requestHandler(
|
||||
{ url: requrl },
|
||||
{
|
||||
setHeader: jest.genMockFunction(),
|
||||
end: function(res) {
|
||||
resolve(res);
|
||||
}
|
||||
|
|
|
@ -358,13 +358,17 @@ Server.prototype.processRequest = function(req, res, next) {
|
|||
building.then(
|
||||
function(p) {
|
||||
if (requestType === 'bundle') {
|
||||
res.end(p.getSource({
|
||||
var bundleSource = p.getSource({
|
||||
inlineSourceMap: options.inlineSourceMap,
|
||||
minify: options.minify,
|
||||
}));
|
||||
});
|
||||
res.setHeader('Content-Type', 'application/javascript');
|
||||
res.end(bundleSource);
|
||||
Activity.endEvent(startReqEventId);
|
||||
} else if (requestType === 'map') {
|
||||
res.end(JSON.stringify(p.getSourceMap()));
|
||||
var sourceMap = JSON.stringify(p.getSourceMap());
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(sourceMap);
|
||||
Activity.endEvent(startReqEventId);
|
||||
}
|
||||
},
|
||||
|
|
|
@ -17,7 +17,19 @@ function attachToServer(server, path) {
|
|||
});
|
||||
var clients = [];
|
||||
|
||||
function sendSpecial(message) {
|
||||
clients.forEach(function (cn) {
|
||||
try {
|
||||
cn.send(JSON.stringify(message));
|
||||
} catch(e) {
|
||||
console.warn('WARN: ' + e.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
wss.on('connection', function(ws) {
|
||||
var id = Math.random().toString(15).slice(10, 20);
|
||||
sendSpecial({$open: id});
|
||||
clients.push(ws);
|
||||
|
||||
var allClientsExcept = function(ws) {
|
||||
|
@ -26,10 +38,12 @@ function attachToServer(server, path) {
|
|||
|
||||
ws.onerror = function() {
|
||||
clients = allClientsExcept(ws);
|
||||
sendSpecial({$error: id});
|
||||
};
|
||||
|
||||
ws.onclose = function() {
|
||||
clients = allClientsExcept(ws);
|
||||
sendSpecial({$close: id});
|
||||
};
|
||||
|
||||
ws.on('message', function(message) {
|
||||
|
|
Loading…
Reference in New Issue