| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 | 
							- /* @flow */
 - import Platform from '../react/Platform';
 - 
 - import { ColorPalette } from './components';
 - 
 - declare type StyleSheet = Object;
 - export type StyleType = StyleSheet | Array<StyleSheet>;
 - 
 - /**
 -  * RegExp pattern for long HEX color format.
 -  */
 - const HEX_LONG_COLOR_FORMAT
 -     = /^#([0-9A-F]{2,2})([0-9A-F]{2,2})([0-9A-F]{2,2})$/i;
 - 
 - /**
 -  * RegExp pattern for short HEX color format.
 -  */
 - const HEX_SHORT_COLOR_FORMAT
 -     = /^#([0-9A-F]{1,1})([0-9A-F]{1,1})([0-9A-F]{1,1})$/i;
 - 
 - /**
 -  * RegExp pattern for RGB color format.
 -  */
 - const RGB_COLOR_FORMAT = /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/i;
 - 
 - /**
 -  * RegExp pattern for RGBA color format.
 -  */
 - const RGBA_COLOR_FORMAT
 -     = /^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*([0-9.]+)\)$/i;
 - 
 - /**
 -  * The list of the well-known style properties which may not be numbers on Web
 -  * but must be numbers on React Native.
 -  *
 -  * @private
 -  */
 - const _WELL_KNOWN_NUMBER_PROPERTIES = [ 'height', 'width' ];
 - 
 - /**
 -  * Function to convert complex StyleType styles into a single flat object,
 -  * so then they can be deconstructed for further processing.
 -  *
 -  * @param {Styletype} st - The complex style type.
 -  * @returns {Object}
 -  */
 - export function styleTypeToObject(st: StyleType): Object {
 -     if (!st) {
 -         return {};
 -     }
 - 
 -     if (Array.isArray(st)) {
 -         const flatStyle = {};
 - 
 -         for (const styleElement of st) {
 -             Object.assign(flatStyle, styleTypeToObject(styleElement));
 -         }
 - 
 -         return flatStyle;
 -     }
 - 
 -     return st;
 - }
 - 
 - /**
 -  * Combines the given 2 styles into a single one.
 -  *
 -  * @param {StyleType} a - An object or array of styles.
 -  * @param {StyleType} b - An object or array of styles.
 -  * @private
 -  * @returns {StyleType} - The merged styles.
 -  */
 - export function combineStyles(a: StyleType, b: StyleType): StyleType {
 -     const result: Array<StyleSheet> = [];
 - 
 -     if (a) {
 -         if (Array.isArray(a)) {
 -             result.push(...a);
 -         } else {
 -             result.push(a);
 -         }
 -     }
 - 
 -     if (b) {
 -         if (Array.isArray(b)) {
 -             result.push(...b);
 -         } else {
 -             result.push(b);
 -         }
 -     }
 - 
 -     return result;
 - }
 - 
 - /**
 -  * Create a style sheet using the provided style definitions.
 -  *
 -  * @param {StyleSheet} styles - A dictionary of named style definitions.
 -  * @param {StyleSheet} [overrides={}] - Optional set of additional (often
 -  * platform-dependent/specific) style definitions that will override the base
 -  * (often platform-independent) styles.
 -  * @returns {StyleSheet}
 -  */
 - export function createStyleSheet(
 -         styles: StyleSheet, overrides: StyleSheet = {}): StyleSheet {
 -     const combinedStyles = {};
 - 
 -     for (const k of Object.keys(styles)) {
 -         combinedStyles[k]
 -             = _shimStyles({
 -                 ...styles[k],
 -                 ...overrides[k]
 -             });
 -     }
 - 
 -     return combinedStyles;
 - }
 - 
 - /**
 -  * Works around a bug in react-native or react-native-webrtc on Android which
 -  * causes Views overlaying RTCView to be clipped. Even though we (may) display
 -  * multiple RTCViews, it is enough to apply the fix only to a View with a
 -  * bounding rectangle containing all RTCviews and their overlaying Views.
 -  *
 -  * @param {StyleSheet} styles - An object which represents a stylesheet.
 -  * @public
 -  * @returns {StyleSheet}
 -  */
 - export function fixAndroidViewClipping<T: StyleSheet>(styles: T): T {
 -     if (Platform.OS === 'android') {
 -         styles.borderColor = ColorPalette.appBackground;
 -         styles.borderWidth = 1;
 -     }
 - 
 -     return styles;
 - }
 - 
 - /**
 -  * Returns an rgba format of the provided color if it's in hex or rgb format.
 -  *
 -  * NOTE: The function will return the same color if it's not in one of those
 -  * two formats (e.g. 'white').
 -  *
 -  * @param {string} color - The string representation of the color in rgb or hex
 -  * format.
 -  * @param {number} alpha - The alpha value to apply.
 -  * @returns {string}
 -  */
 - export function getRGBAFormat(color: string, alpha: number): string {
 -     let match = color.match(HEX_LONG_COLOR_FORMAT);
 - 
 -     if (match) {
 -         return `#${match[1]}${match[2]}${match[3]}${_getAlphaInHex(alpha)}`;
 -     }
 - 
 -     match = color.match(HEX_SHORT_COLOR_FORMAT);
 -     if (match) {
 -         return `#${match[1]}${match[1]}${match[2]}${match[2]}${match[3]}${
 -             match[3]}${_getAlphaInHex(alpha)}`;
 -     }
 - 
 -     match = color.match(RGB_COLOR_FORMAT);
 -     if (match) {
 -         return `rgba(${match[1]}, ${match[2]}, ${match[3]}, ${alpha})`;
 -     }
 - 
 -     return color;
 - }
 - 
 - /**
 -  * Decides if a color is light or dark based on the ITU-R BT.709 and W3C
 -  * recommendations.
 -  *
 -  * NOTE: Please see https://www.w3.org/TR/WCAG20/#relativeluminancedef.
 -  *
 -  * @param {string} color - The color in rgb, rgba or hex format.
 -  * @returns {boolean}
 -  */
 - export function isDarkColor(color: string): boolean {
 -     const rgb = _getRGBObjectFormat(color);
 - 
 -     return ((_getColorLuminance(rgb.r) * 0.2126)
 -     + (_getColorLuminance(rgb.g) * 0.7152)
 -     + (_getColorLuminance(rgb.b) * 0.0722)) <= 0.179;
 - }
 - 
 - /**
 -  * Converts an [0..1] alpha value into HEX.
 -  *
 -  * @param {number} alpha - The alpha value to convert.
 -  * @returns {string}
 -  */
 - function _getAlphaInHex(alpha: number): string {
 -     return Number(Math.round(255 * alpha)).toString(16)
 -         .padStart(2, '0');
 - }
 - 
 - /**
 -  * Calculated the color luminance component for an individual color channel.
 -  *
 -  * NOTE: Please see https://www.w3.org/TR/WCAG20/#relativeluminancedef.
 -  *
 -  * @param {number} c - The color which we need the individual luminance
 -  * for.
 -  * @returns {number}
 -  */
 - function _getColorLuminance(c: number): number {
 -     return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
 - }
 - 
 - /**
 -  * Parses a color string into an object containing the RGB values as numbers.
 -  *
 -  * NOTE: Object properties are not alpha-sorted for sanity.
 -  *
 -  * @param {string} color - The color to convert.
 -  * @returns {{
 -  *     r: number,
 -  *     g: number,
 -  *     b: number
 -  * }}
 -  */
 - function _getRGBObjectFormat(color: string): {r: number, g: number, b: number} {
 -     let match = color.match(HEX_LONG_COLOR_FORMAT);
 - 
 -     if (match) {
 -         return {
 -             r: parseInt(match[1], 16) / 255.0,
 -             g: parseInt(match[2], 16) / 255.0,
 -             b: parseInt(match[3], 16) / 255.0
 -         };
 -     }
 - 
 -     match = color.match(HEX_SHORT_COLOR_FORMAT);
 -     if (match) {
 -         return {
 -             r: parseInt(`${match[1]}${match[1]}`, 16) / 255.0,
 -             g: parseInt(`${match[2]}${match[2]}`, 16) / 255.0,
 -             b: parseInt(`${match[3]}${match[3]}`, 16) / 255.0
 -         };
 -     }
 - 
 -     match = color.match(RGB_COLOR_FORMAT) || color.match(RGBA_COLOR_FORMAT);
 -     if (match) {
 -         return {
 -             r: parseInt(match[1], 10) / 255.0,
 -             g: parseInt(match[2], 10) / 255.0,
 -             b: parseInt(match[3], 10) / 255.0
 -         };
 -     }
 - 
 -     return {
 -         r: 0,
 -         g: 0,
 -         b: 0
 -     };
 - }
 - 
 - /**
 -  * Shims style properties to work correctly on native. Allows us to minimize the
 -  * number of style declarations that need to be set or overridden for specific
 -  * platforms.
 -  *
 -  * @param {StyleSheet} styles - An object which represents a stylesheet.
 -  * @private
 -  * @returns {StyleSheet}
 -  */
 - function _shimStyles<T: StyleSheet>(styles: T): T {
 -     // Certain style properties may not be numbers on Web but must be numbers on
 -     // React Native. For example, height and width may be expressed in percent
 -     // on Web but React Native will not understand them and we will get errors
 -     // (at least during development). Convert such well-known properties to
 -     // numbers if possible; otherwise, remove them to avoid runtime errors.
 -     for (const k of _WELL_KNOWN_NUMBER_PROPERTIES) {
 -         const v = styles[k];
 -         const typeofV = typeof v;
 - 
 -         if (typeofV !== 'undefined' && typeofV !== 'number') {
 -             const numberV = Number(v);
 - 
 -             if (Number.isNaN(numberV)) {
 -                 delete styles[k];
 -             } else {
 -                 styles[k] = numberV;
 -             }
 -         }
 -     }
 - 
 -     return styles;
 - }
 
 
  |