Skip to content

Commit

Permalink
Move color processing to JS
Browse files Browse the repository at this point in the history
Reviewed By: @vjeux

Differential Revision: D2346353
  • Loading branch information
Alexsander Akers authored and facebook-github-bot-7 committed Sep 18, 2015
1 parent 6078a4f commit 9a2d05d
Show file tree
Hide file tree
Showing 17 changed files with 292 additions and 424 deletions.
4 changes: 2 additions & 2 deletions Examples/UIExplorer/BorderExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ var styles = StyleSheet.create({
},
border1: {
borderWidth: 10,
borderColor: '#a52a2a',
borderColor: 'brown',
},
borderRadius: {
borderWidth: 10,
borderRadius: 10,
borderColor: '#00ffff',
borderColor: 'cyan',
},
border2: {
borderWidth: 10,
Expand Down
10 changes: 5 additions & 5 deletions Examples/UIExplorer/PanResponderExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,22 @@
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* @flow
* @flow-weak
*/
'use strict';

var React = require('react-native');
var {
StyleSheet,
PanResponder,
StyleSheet,
View,
processColor,
} = React;

var CIRCLE_SIZE = 80;
var CIRCLE_COLOR = 'blue';
var CIRCLE_HIGHLIGHT_COLOR = 'green';


var PanResponderExample = React.createClass({

statics: {
Expand Down Expand Up @@ -78,13 +78,13 @@ var PanResponderExample = React.createClass({

_highlight: function() {
this.circle && this.circle.setNativeProps({
backgroundColor: CIRCLE_HIGHLIGHT_COLOR
backgroundColor: processColor(CIRCLE_HIGHLIGHT_COLOR)
});
},

_unHighlight: function() {
this.circle && this.circle.setNativeProps({
backgroundColor: CIRCLE_COLOR
backgroundColor: processColor(CIRCLE_COLOR)
});
},

Expand Down
4 changes: 0 additions & 4 deletions Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@
83636F8F1B53F22C009F943E /* RCTUIManagerScenarioTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 83636F8E1B53F22C009F943E /* RCTUIManagerScenarioTests.m */; };
8385CEF51B873B5C00C6273E /* RCTImageLoaderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8385CEF41B873B5C00C6273E /* RCTImageLoaderTests.m */; };
8385CF041B87479200C6273E /* RCTImageLoaderHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 8385CF031B87479200C6273E /* RCTImageLoaderHelpers.m */; };
83A936C81B7E0F08005B9C36 /* RCTConvert_UIColorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A936C71B7E0F08005B9C36 /* RCTConvert_UIColorTests.m */; };
D85B829E1AB6D5D7003F4FE2 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D85B829C1AB6D5CE003F4FE2 /* libRCTVibration.a */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -231,7 +230,6 @@
8385CEF41B873B5C00C6273E /* RCTImageLoaderTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTImageLoaderTests.m; sourceTree = "<group>"; };
8385CF031B87479200C6273E /* RCTImageLoaderHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTImageLoaderHelpers.m; sourceTree = "<group>"; };
8385CF051B8747A000C6273E /* RCTImageLoaderHelpers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTImageLoaderHelpers.h; sourceTree = "<group>"; };
83A936C71B7E0F08005B9C36 /* RCTConvert_UIColorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTConvert_UIColorTests.m; sourceTree = "<group>"; };
D85B82911AB6D5CE003F4FE2 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = ../../Libraries/Vibration/RCTVibration.xcodeproj; sourceTree = "<group>"; };
/* End PBXFileReference section */

Expand Down Expand Up @@ -385,7 +383,6 @@
138D6A151B53CD440074A87E /* RCTCacheTests.m */,
1497CFA61B21F5E400C1F8F2 /* RCTContextExecutorTests.m */,
1497CFA71B21F5E400C1F8F2 /* RCTConvert_NSURLTests.m */,
83A936C71B7E0F08005B9C36 /* RCTConvert_UIColorTests.m */,
1497CFA81B21F5E400C1F8F2 /* RCTConvert_UIFontTests.m */,
1497CFA91B21F5E400C1F8F2 /* RCTEventDispatcherTests.m */,
1300627E1B59179B0043FE5A /* RCTGzipTests.m */,
Expand Down Expand Up @@ -846,7 +843,6 @@
138D6A171B53CD440074A87E /* RCTCacheTests.m in Sources */,
13DB03481B5D2ED500C27245 /* RCTJSONTests.m in Sources */,
1497CFAC1B21F5E400C1F8F2 /* RCTAllocationTests.m in Sources */,
83A936C81B7E0F08005B9C36 /* RCTConvert_UIColorTests.m in Sources */,
13DF61B61B67A45000EDB188 /* RCTMethodArgumentTests.m in Sources */,
138D6A181B53CD440074A87E /* RCTShadowViewTests.m in Sources */,
8385CF041B87479200C6273E /* RCTImageLoaderHelpers.m in Sources */,
Expand Down
79 changes: 0 additions & 79 deletions Examples/UIExplorer/UIExplorerUnitTests/RCTConvert_UIColorTests.m

This file was deleted.

32 changes: 2 additions & 30 deletions Libraries/Components/TextInput/TextInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,30 +40,7 @@ var notMultiline = {
onSubmitEditing: true,
};

var AndroidTextInputAttributes = {
autoCapitalize: true,
autoCorrect: true,
autoFocus: true,
textAlign: true,
textAlignVertical: true,
keyboardType: true,
mostRecentEventCount: true,
multiline: true,
numberOfLines: true,
password: true,
placeholder: true,
placeholderTextColor: true,
text: true,
testID: true,
underlineColorAndroid: true,
editable : true,
};

var viewConfigAndroid = {
uiViewClassName: 'AndroidTextInput',
validAttributes: AndroidTextInputAttributes,
};

var AndroidTextInput = requireNativeComponent('AndroidTextInput', null);
var RCTTextView = requireNativeComponent('RCTTextView', null);
var RCTTextField = requireNativeComponent('RCTTextField', null);

Expand Down Expand Up @@ -317,7 +294,7 @@ var TextInput = React.createClass({
mixins: [NativeMethodsMixin, TimerMixin],

viewConfig: ((Platform.OS === 'ios' ? RCTTextField.viewConfig :
(Platform.OS === 'android' ? viewConfigAndroid : {})) : Object),
(Platform.OS === 'android' ? AndroidTextInput.viewConfig : {})) : Object),

isFocused: function(): boolean {
return TextInputState.currentlyFocusedField() ===
Expand Down Expand Up @@ -578,9 +555,4 @@ var styles = StyleSheet.create({
},
});

var AndroidTextInput = createReactNativeComponentClass({
validAttributes: AndroidTextInputAttributes,
uiViewClassName: 'AndroidTextInput',
});

module.exports = TextInput;
7 changes: 2 additions & 5 deletions Libraries/Components/ToolbarAndroid/ToolbarAndroid.android.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ var React = require('React');
var ReactNativeViewAttributes = require('ReactNativeViewAttributes');
var ReactPropTypes = require('ReactPropTypes');

var createReactNativeComponentClass = require('createReactNativeComponentClass');
var requireNativeComponent = require('requireNativeComponent');

/**
* React component that wraps the Android-only [`Toolbar` widget][0]. A Toolbar can display a logo,
Expand Down Expand Up @@ -166,9 +166,6 @@ var toolbarAttributes = {
titleColor: true,
};

var NativeToolbar = createReactNativeComponentClass({
validAttributes: toolbarAttributes,
uiViewClassName: 'ToolbarAndroid',
});
var NativeToolbar = requireNativeComponent('ToolbarAndroid', null);

module.exports = ToolbarAndroid;
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ var createReactNativeComponentClass = require('createReactNativeComponentClass')
var createStrictShapeTypeChecker = require('createStrictShapeTypeChecker');
var ensurePositiveDelayProps = require('ensurePositiveDelayProps');
var onlyChild = require('onlyChild');
var processColor = require('processColor');

var rippleBackgroundPropType = createStrictShapeTypeChecker({
type: React.PropTypes.oneOf(['RippleAndroid']),
Expand Down Expand Up @@ -112,7 +113,7 @@ var TouchableNativeFeedback = React.createClass({
return {type: 'ThemeAttrAndroid', attribute: 'selectableItemBackgroundBorderless'};
},
Ripple: function(color, borderless) {
return {type: 'RippleAndroid', color: color, borderless: borderless};
return {type: 'RippleAndroid', color: processColor(color), borderless: borderless};
},
},

Expand Down
27 changes: 23 additions & 4 deletions Libraries/ReactIOS/NativeMethodsMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,34 @@ var NativeMethodsMixin = {
break;
}
}
var style = precomputeStyle(flattenStyle(nativeProps.style));

var validAttributes = this.viewConfig.validAttributes;
var hasProcessedProps = false;
var processedProps = {};
for (var key in nativeProps) {
var process = validAttributes[key] && validAttributes[key].process;
if (process) {
hasProcessedProps = true;
processedProps[key] = process(nativeProps[key]);
}
}

var style = precomputeStyle(
flattenStyle(processedProps.style || nativeProps.style),
this.viewConfig.validAttributes
);

var props = null;
if (hasOnlyStyle) {
props = style;
} else if (!style) {
props = nativeProps;
} else {
props = mergeFast(nativeProps, style);
props = nativeProps;
if (hasProcessedProps) {
props = mergeFast(props, processedProps);
}
if (style) {
props = mergeFast(props, style);
}
}

RCTUIManager.updateView(
Expand Down
27 changes: 26 additions & 1 deletion Libraries/ReactIOS/requireNativeComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ var createReactNativeComponentClass = require('createReactNativeComponentClass')
var insetsDiffer = require('insetsDiffer');
var pointsDiffer = require('pointsDiffer');
var matricesDiffer = require('matricesDiffer');
var processColor = require('processColor');
var sizesDiffer = require('sizesDiffer');
var verifyPropTypes = require('verifyPropTypes');
var warning = require('warning');
Expand Down Expand Up @@ -57,8 +58,22 @@ function requireNativeComponent(
viewConfig.validAttributes = {};
viewConfig.propTypes = componentInterface && componentInterface.propTypes;
for (var key in nativeProps) {
var useAttribute = false;
var attribute = {};

var differ = TypeToDifferMap[nativeProps[key]];
viewConfig.validAttributes[key] = differ ? {diff: differ} : true;
if (differ) {
attribute.diff = differ;
useAttribute = true;
}

var processor = TypeToProcessorMap[nativeProps[key]];
if (processor) {
attribute.process = processor;
useAttribute = true;
}

viewConfig.validAttributes[key] = useAttribute ? attribute : true;
}
if (__DEV__) {
componentInterface && verifyPropTypes(
Expand All @@ -80,4 +95,14 @@ var TypeToDifferMap = {
// (not yet implemented)
};

var TypeToProcessorMap = {
// iOS Types
CGColor: processColor,
CGColorArray: processColor,
UIColor: processColor,
UIColorArray: processColor,
// Android Types
Color: processColor,
};

module.exports = requireNativeComponent;
12 changes: 11 additions & 1 deletion Libraries/ReactNative/ReactNativeBaseComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,23 @@ ReactNativeBaseComponent.Mixin = {
validAttributes
);

for (var key in updatePayload) {
var process = validAttributes[key] && validAttributes[key].process;
if (process) {
updatePayload[key] = process(updatePayload[key]);
}
}

// The style property is a deeply nested element which includes numbers
// to represent static objects. Most of the time, it doesn't change across
// renders, so it's faster to spend the time checking if it is different
// before actually doing the expensive flattening operation in order to
// compute the diff.
if (styleDiffer(nextProps.style, prevProps.style)) {
var nextFlattenedStyle = precomputeStyle(flattenStyle(nextProps.style));
var nextFlattenedStyle = precomputeStyle(
flattenStyle(nextProps.style),
this.viewConfig.validAttributes
);
updatePayload = diffRawProperties(
updatePayload,
this.previousFlattenedStyle,
Expand Down
13 changes: 13 additions & 0 deletions Libraries/ReactNative/ReactNativeStyleAttributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ var ViewStylePropTypes = require('ViewStylePropTypes');

var keyMirror = require('keyMirror');
var matricesDiffer = require('matricesDiffer');
var processColor = require('processColor');
var sizesDiffer = require('sizesDiffer');

var ReactNativeStyleAttributes = {
Expand All @@ -32,4 +33,16 @@ ReactNativeStyleAttributes.shadowOffset = { diff: sizesDiffer };
// Do not rely on this attribute.
ReactNativeStyleAttributes.decomposedMatrix = 'decomposedMatrix';

var colorAttributes = { process: processColor };
ReactNativeStyleAttributes.backgroundColor = colorAttributes;
ReactNativeStyleAttributes.borderBottomColor = colorAttributes;
ReactNativeStyleAttributes.borderColor = colorAttributes;
ReactNativeStyleAttributes.borderLeftColor = colorAttributes;
ReactNativeStyleAttributes.borderRightColor = colorAttributes;
ReactNativeStyleAttributes.borderTopColor = colorAttributes;
ReactNativeStyleAttributes.color = colorAttributes;
ReactNativeStyleAttributes.shadowColor = colorAttributes;
ReactNativeStyleAttributes.textDecorationColor = colorAttributes;
ReactNativeStyleAttributes.tintColor = colorAttributes;

module.exports = ReactNativeStyleAttributes;
Loading

0 comments on commit 9a2d05d

Please sign in to comment.