mirror of
https://github.com/zoriya/react-native-web.git
synced 2026-05-31 09:44:21 +00:00
[fix] RTL style registration and resolution
* Lazy-register RTL variants to generate class names * Don't RTL-flip translateX
This commit is contained in:
@@ -104,7 +104,6 @@ var styles = StyleSheet.create({
|
|||||||
height: CIRCLE_SIZE,
|
height: CIRCLE_SIZE,
|
||||||
borderRadius: CIRCLE_SIZE / 2,
|
borderRadius: CIRCLE_SIZE / 2,
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
left: 0,
|
|
||||||
top: 0,
|
top: 0,
|
||||||
},
|
},
|
||||||
container: {
|
container: {
|
||||||
|
|||||||
@@ -7,13 +7,14 @@ import flattenArray from '../../modules/flattenArray';
|
|||||||
import flattenStyle from './flattenStyle';
|
import flattenStyle from './flattenStyle';
|
||||||
import I18nManager from '../I18nManager';
|
import I18nManager from '../I18nManager';
|
||||||
import i18nStyle from './i18nStyle';
|
import i18nStyle from './i18nStyle';
|
||||||
import mapKeyValue from '../../modules/mapKeyValue';
|
|
||||||
import { prefixInlineStyles } from '../../modules/prefixStyles';
|
import { prefixInlineStyles } from '../../modules/prefixStyles';
|
||||||
import ReactNativePropRegistry from '../../modules/ReactNativePropRegistry';
|
import ReactNativePropRegistry from '../../modules/ReactNativePropRegistry';
|
||||||
import StyleManager from './StyleManager';
|
import StyleManager from './StyleManager';
|
||||||
|
|
||||||
|
const emptyObject = {};
|
||||||
|
|
||||||
const createCacheKey = id => {
|
const createCacheKey = id => {
|
||||||
const prefix = I18nManager.isRTL ? 'rtl' : 'ltr';
|
const prefix = 'rn';
|
||||||
return `${prefix}-${id}`;
|
return `${prefix}-${id}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -21,7 +22,7 @@ const classListToString = list => list.join(' ').trim();
|
|||||||
|
|
||||||
class StyleRegistry {
|
class StyleRegistry {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.cache = {};
|
this.cache = { ltr: {}, rtl: {} };
|
||||||
this.styleManager = new StyleManager();
|
this.styleManager = new StyleManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,30 +35,38 @@ class StyleRegistry {
|
|||||||
*/
|
*/
|
||||||
register(flatStyle) {
|
register(flatStyle) {
|
||||||
const id = ReactNativePropRegistry.register(flatStyle);
|
const id = ReactNativePropRegistry.register(flatStyle);
|
||||||
const key = createCacheKey(id);
|
this._registerById(id);
|
||||||
const style = createReactDOMStyle(i18nStyle(flatStyle));
|
|
||||||
const classList = mapKeyValue(style, (prop, value) => {
|
|
||||||
if (value != null) {
|
|
||||||
return this.styleManager.setDeclaration(prop, value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const className = classList.join(' ').trim();
|
|
||||||
this.cache[key] = { classList, className };
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_registerById(id) {
|
||||||
|
const dir = I18nManager.isRTL ? 'rtl' : 'ltr';
|
||||||
|
if (!this.cache[dir][id]) {
|
||||||
|
const style = flattenStyle(id);
|
||||||
|
const domStyle = createReactDOMStyle(i18nStyle(style));
|
||||||
|
Object.keys(domStyle).forEach(styleProp => {
|
||||||
|
const value = domStyle[styleProp];
|
||||||
|
if (value != null) {
|
||||||
|
this.styleManager.setDeclaration(styleProp, value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.cache[dir][id] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves a React Native style object to DOM attributes
|
* Resolves a React Native style object to DOM attributes
|
||||||
*/
|
*/
|
||||||
resolve(reactNativeStyle, options) {
|
resolve(reactNativeStyle, options = emptyObject) {
|
||||||
if (!reactNativeStyle) {
|
if (!reactNativeStyle) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fast and cachable
|
// fast and cachable
|
||||||
if (typeof reactNativeStyle === 'number') {
|
if (typeof reactNativeStyle === 'number') {
|
||||||
|
this._registerById(reactNativeStyle);
|
||||||
const key = createCacheKey(reactNativeStyle);
|
const key = createCacheKey(reactNativeStyle);
|
||||||
return this._resolveStyleIfNeeded(reactNativeStyle, { key, ...options });
|
return this._resolveStyleIfNeeded(reactNativeStyle, options, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolve a plain RN style object
|
// resolve a plain RN style object
|
||||||
@@ -71,13 +80,15 @@ class StyleRegistry {
|
|||||||
const flatArray = flattenArray(reactNativeStyle);
|
const flatArray = flattenArray(reactNativeStyle);
|
||||||
let isArrayOfNumbers = true;
|
let isArrayOfNumbers = true;
|
||||||
for (let i = 0; i < flatArray.length; i++) {
|
for (let i = 0; i < flatArray.length; i++) {
|
||||||
if (typeof flatArray[i] !== 'number') {
|
const id = flatArray[i];
|
||||||
|
if (typeof id !== 'number') {
|
||||||
isArrayOfNumbers = false;
|
isArrayOfNumbers = false;
|
||||||
break;
|
} else {
|
||||||
|
this._registerById(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const key = isArrayOfNumbers ? createCacheKey(flatArray.join('-')) : null;
|
const key = isArrayOfNumbers ? createCacheKey(flatArray.join('-')) : null;
|
||||||
return this._resolveStyleIfNeeded(flatArray, { key, ...options });
|
return this._resolveStyleIfNeeded(flatArray, options, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -166,15 +177,16 @@ class StyleRegistry {
|
|||||||
/**
|
/**
|
||||||
* Caching layer over 'resolveStyle'
|
* Caching layer over 'resolveStyle'
|
||||||
*/
|
*/
|
||||||
_resolveStyleIfNeeded(style, { key, ...rest }) {
|
_resolveStyleIfNeeded(style, options, key) {
|
||||||
|
const dir = I18nManager.isRTL ? 'rtl' : 'ltr';
|
||||||
if (key) {
|
if (key) {
|
||||||
if (!this.cache[key]) {
|
if (!this.cache[dir][key]) {
|
||||||
// slow: convert style object to props and cache
|
// slow: convert style object to props and cache
|
||||||
this.cache[key] = this._resolveStyle(style, rest);
|
this.cache[dir][key] = this._resolveStyle(style, options);
|
||||||
}
|
}
|
||||||
return this.cache[key];
|
return this.cache[dir][key];
|
||||||
}
|
}
|
||||||
return this._resolveStyle(style, rest);
|
return this._resolveStyle(style, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,12 @@
|
|||||||
|
|
||||||
exports[`apis/StyleSheet/StyleRegistry resolve with register before RTL, resolves to className 1`] = `
|
exports[`apis/StyleSheet/StyleRegistry resolve with register before RTL, resolves to className 1`] = `
|
||||||
Object {
|
Object {
|
||||||
"classList": Array [],
|
"classList": Array [
|
||||||
"className": "",
|
"rn-marginRight-zso239",
|
||||||
"style": Object {
|
"rn-right-1bnbe1j",
|
||||||
"marginRight": "10px",
|
"rn-textAlign-1ff274t",
|
||||||
"right": "12.34%",
|
],
|
||||||
"textAlign": "right",
|
"className": "rn-marginRight-zso239 rn-right-1bnbe1j rn-textAlign-1ff274t",
|
||||||
},
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|||||||
@@ -43,17 +43,6 @@ const flipProperty = (prop: String): String => {
|
|||||||
return PROPERTIES_TO_SWAP.hasOwnProperty(prop) ? PROPERTIES_TO_SWAP[prop] : prop;
|
return PROPERTIES_TO_SWAP.hasOwnProperty(prop) ? PROPERTIES_TO_SWAP[prop] : prop;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* BiDi flip translateX
|
|
||||||
*/
|
|
||||||
const flipTransform = (transform: Object): Object => {
|
|
||||||
const translateX = transform.translateX;
|
|
||||||
if (translateX != null) {
|
|
||||||
transform.translateX = additiveInverse(translateX);
|
|
||||||
}
|
|
||||||
return transform;
|
|
||||||
};
|
|
||||||
|
|
||||||
const swapLeftRight = (value: String): String => {
|
const swapLeftRight = (value: String): String => {
|
||||||
return value === 'left' ? 'right' : value === 'right' ? 'left' : value;
|
return value === 'left' ? 'right' : value === 'right' ? 'left' : value;
|
||||||
};
|
};
|
||||||
@@ -81,8 +70,6 @@ const i18nStyle = originalStyle => {
|
|||||||
} else if (prop === 'textShadowOffset') {
|
} else if (prop === 'textShadowOffset') {
|
||||||
nextStyle[prop] = value;
|
nextStyle[prop] = value;
|
||||||
nextStyle[prop].width = additiveInverse(value.width);
|
nextStyle[prop].width = additiveInverse(value.width);
|
||||||
} else if (prop === 'transform' && Array.isArray(value)) {
|
|
||||||
nextStyle[prop] = style[prop].map(flipTransform);
|
|
||||||
} else {
|
} else {
|
||||||
nextStyle[prop] = style[prop];
|
nextStyle[prop] = style[prop];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user