Static type check for int params + migrate colorInt to just int.

Differential Revision: D2475618

committer: Service User <svcscm@fb.com>
This commit is contained in:
Krzysztof Magiera
2015-09-24 03:02:33 -07:00
committed by facebook-github-bot-9
parent 944fa4d635
commit 6c3fb77f30
17 changed files with 78 additions and 221 deletions

View File

@@ -73,7 +73,7 @@ public class BaseViewPropertyApplicator {
public static void applyCommonViewProperties(View view, CatalystStylesDiffMap props) {
if (props.hasKey(ViewProps.BACKGROUND_COLOR)) {
final int backgroundColor = props.getColorInt(ViewProps.BACKGROUND_COLOR, Color.TRANSPARENT);
final int backgroundColor = props.getInt(ViewProps.BACKGROUND_COLOR, Color.TRANSPARENT);
view.setBackgroundColor(backgroundColor);
}
if (props.hasKey(PROP_DECOMPOSED_MATRIX)) {

View File

@@ -1,155 +0,0 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.react.uimanager;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.graphics.Color;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.common.annotations.VisibleForTesting;
/**
* Translates the different color formats to their actual colors.
*/
public class CSSColorUtil {
static final Pattern RGB_COLOR_PATTERN =
Pattern.compile("rgb\\(\\s*([0-9]{1,3}),\\s*([0-9]{1,3}),\\s*([0-9]{1,3})\\s*\\)");
static final Pattern RGBA_COLOR_PATTERN = Pattern.compile(
"rgba\\(\\s*([0-9]{1,3}),\\s*([0-9]{1,3}),\\s*([0-9]{1,3})\\s*,\\s*(0*(\\.\\d{1,3})?|1(\\.0+)?)\\)");
private static final HashMap<String, Integer> sColorNameMap = new HashMap<String, Integer>();
static {
// List of HTML4 colors: http://www.w3.org/TR/css3-color/#html4
sColorNameMap.put("black", Color.argb(255, 0, 0, 0));
sColorNameMap.put("silver", Color.argb(255, 192, 192, 192));
sColorNameMap.put("gray", Color.argb(255, 128, 128, 128));
sColorNameMap.put("grey", Color.argb(255, 128, 128, 128));
sColorNameMap.put("white", Color.argb(255, 255, 255, 255));
sColorNameMap.put("maroon", Color.argb(255, 128, 0, 0));
sColorNameMap.put("red", Color.argb(255, 255, 0, 0));
sColorNameMap.put("purple", Color.argb(255, 128, 0, 128));
sColorNameMap.put("fuchsia", Color.argb(255, 255, 0, 255));
sColorNameMap.put("green", Color.argb(255, 0, 128, 0));
sColorNameMap.put("lime", Color.argb(255, 0, 255, 0));
sColorNameMap.put("olive", Color.argb(255, 128, 128, 0));
sColorNameMap.put("yellow", Color.argb(255, 255, 255, 0));
sColorNameMap.put("navy", Color.argb(255, 0, 0, 128));
sColorNameMap.put("blue", Color.argb(255, 0, 0, 255));
sColorNameMap.put("teal", Color.argb(255, 0, 128, 128));
sColorNameMap.put("aqua", Color.argb(255, 0, 255, 255));
// Extended colors
sColorNameMap.put("orange", Color.argb(255, 255, 165, 0));
sColorNameMap.put("transparent", Color.argb(0, 0, 0, 0));
}
/**
* Parses the given color string and returns the corresponding color int value.
*
* The following color formats are supported:
* <ul>
* <li>#rgb - Example: "#F02" (will be expanded to "#FF0022")</li>
* <li>#rrggbb - Example: "#FF0022"</li>
* <li>rgb(r, g, b) - Example: "rgb(255, 0, 34)"</li>
* <li>rgba(r, g, b, a) - Example: "rgba(255, 0, 34, 0.2)"</li>
* <li>Color names - Example: "red" or "transparent"</li>
* </ul>
* @param colorString the string representation of the color
* @return the color int
*/
public static int getColor(String colorString) {
if (colorString.startsWith("rgb(")) {
Matcher rgbMatcher = RGB_COLOR_PATTERN.matcher(colorString);
if (rgbMatcher.matches()) {
return Color.rgb(
validateColorComponent(Integer.parseInt(rgbMatcher.group(1))),
validateColorComponent(Integer.parseInt(rgbMatcher.group(2))),
validateColorComponent(Integer.parseInt(rgbMatcher.group(3))));
} else {
throw new JSApplicationIllegalArgumentException("Invalid color: " + colorString);
}
} else if (colorString.startsWith("rgba(")) {
Matcher rgbaMatcher = RGBA_COLOR_PATTERN.matcher(colorString);
if (rgbaMatcher.matches()) {
return Color.argb(
(int) (Float.parseFloat(rgbaMatcher.group(4)) * 255),
validateColorComponent(Integer.parseInt(rgbaMatcher.group(1))),
validateColorComponent(Integer.parseInt(rgbaMatcher.group(2))),
validateColorComponent(Integer.parseInt(rgbaMatcher.group(3))));
} else {
throw new JSApplicationIllegalArgumentException("Invalid color: " + colorString);
}
} else if (colorString.startsWith("#")) {
if (colorString.length() == 4) {
int r = parseHexChar(colorString.charAt(1));
int g = parseHexChar(colorString.charAt(2));
int b = parseHexChar(colorString.charAt(3));
// double the character
// since parseHexChar only returns values from 0-15, we don't need & 0xff
r = r | (r << 4);
g = g | (g << 4);
b = b | (b << 4);
return Color.rgb(r, g, b);
} else {
// check if we have #RRGGBB
if (colorString.length() == 7) {
// Color.parseColor(...) can throw an IllegalArgumentException("Unknown color").
// For consistency, we hide the original exception and throw our own exception instead.
try {
return Color.parseColor(colorString);
} catch (IllegalArgumentException ex) {
throw new JSApplicationIllegalArgumentException("Invalid color: " + colorString);
}
} else {
throw new JSApplicationIllegalArgumentException("Invalid color: " + colorString);
}
}
} else {
Integer color = sColorNameMap.get(colorString.toLowerCase());
if (color != null) {
return color;
}
throw new JSApplicationIllegalArgumentException("Unknown color: " + colorString);
}
}
/**
* Convert a single hex character (0-9, a-f, A-F) to a number (0-15).
*
* @param hexChar the hex character to convert
* @return the value between 0 and 15
*/
@VisibleForTesting
/*package*/ static int parseHexChar(char hexChar) {
if (hexChar >= '0' && hexChar <= '9') {
return hexChar - '0';
} else if (hexChar >= 'A' && hexChar <= 'F') {
return hexChar - 'A' + 10;
} else if (hexChar >= 'a' && hexChar <= 'f') {
return hexChar - 'a' + 10;
}
throw new JSApplicationIllegalArgumentException("Invalid hex character: " + hexChar);
}
private static int validateColorComponent(int color) {
if (color < 0 || color > 255) {
throw new JSApplicationIllegalArgumentException("Invalid color component: " + color);
}
return color;
}
}

View File

@@ -64,18 +64,7 @@ public class CatalystStylesDiffMap {
}
public int getInt(String name, int restoreNullToDefaultValue) {
return mBackingMap.isNull(name) ? restoreNullToDefaultValue : (int) mBackingMap.getDouble(name);
}
// Colors have values between 0x00000000 and 0xFFFFFFFF, which fits in an integer, but is sent as
// a double over the bridge. Because color values can be higher than Integer.MAX_VALUE, it is not
// correct to convert doubles to int directly, since they can be truncated to Integer.MAX_VALUE
// instead of being converted to negative values. Converting from double to long maintains the
// initial value, and is then correctly converted to int. This is the expected behavior according
// to the java spec, see http://stackoverflow.com/questions/10641559 for more.
public int getColorInt(String name, int restoreNullToDefaultValue) {
return mBackingMap.isNull(name) ? restoreNullToDefaultValue :
(int) (long) mBackingMap.getDouble(name);
return mBackingMap.isNull(name) ? restoreNullToDefaultValue : mBackingMap.getInt(name);
}
@Nullable