GT2/Ejectable/node_modules/react-native-web/dist/exports/StyleSheet/createStyleResolver.js

282 lines
7.9 KiB
JavaScript
Raw Normal View History

2021-08-16 00:14:59 +00:00
/**
* Copyright (c) Nicolas Gallagher.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
/**
* WARNING: changes to this file in particular can cause significant changes to
* the results of render performance benchmarks.
*/
import { canUseDOM } from 'fbjs/lib/ExecutionEnvironment';
import createCSSStyleSheet from './createCSSStyleSheet';
import createCompileableStyle from './createCompileableStyle';
import createOrderedCSSStyleSheet from './createOrderedCSSStyleSheet';
import flattenArray from '../../modules/flattenArray';
import flattenStyle from './flattenStyle';
import I18nManager from '../I18nManager';
import i18nStyle from './i18nStyle';
import { atomic, classic, inline, stringifyValueWithProperty } from './compile';
import initialRules from './initialRules';
import modality from './modality';
import { STYLE_ELEMENT_ID, STYLE_GROUPS } from './constants';
export default function createStyleResolver() {
var inserted, sheet, cache;
var resolved = {
css: {},
ltr: {},
rtl: {},
rtlNoSwap: {}
};
var init = function init() {
inserted = {
css: {},
ltr: {},
rtl: {},
rtlNoSwap: {}
};
sheet = createOrderedCSSStyleSheet(createCSSStyleSheet(STYLE_ELEMENT_ID));
cache = {};
modality(function (rule) {
return sheet.insert(rule, STYLE_GROUPS.modality);
});
initialRules.forEach(function (rule) {
sheet.insert(rule, STYLE_GROUPS.reset);
});
};
init();
function addToCache(className, prop, value) {
if (!cache[prop]) {
cache[prop] = {};
}
cache[prop][value] = className;
}
function getClassName(prop, value) {
var val = stringifyValueWithProperty(value, prop);
return cache[prop] && cache[prop].hasOwnProperty(val) && cache[prop][val];
}
function _injectRegisteredStyle(id) {
var doLeftAndRightSwapInRTL = I18nManager.doLeftAndRightSwapInRTL,
isRTL = I18nManager.isRTL;
var dir = isRTL ? doLeftAndRightSwapInRTL ? 'rtl' : 'rtlNoSwap' : 'ltr';
if (!inserted[dir][id]) {
var style = createCompileableStyle(i18nStyle(flattenStyle(id)));
var results = atomic(style);
Object.keys(results).forEach(function (key) {
var _results$key = results[key],
identifier = _results$key.identifier,
property = _results$key.property,
rules = _results$key.rules,
value = _results$key.value;
addToCache(identifier, property, value);
rules.forEach(function (rule) {
var group = STYLE_GROUPS.custom[property] || STYLE_GROUPS.atomic;
sheet.insert(rule, group);
});
});
inserted[dir][id] = true;
}
}
/**
* Resolves a React Native style object to DOM attributes
*/
function resolve(style, classList) {
var nextClassList = [];
var props = {};
if (!style && !classList) {
return props;
}
if (Array.isArray(classList)) {
flattenArray(classList).forEach(function (identifier) {
if (identifier) {
if (inserted.css[identifier] == null && resolved.css[identifier] != null) {
var item = resolved.css[identifier];
item.rules.forEach(function (rule) {
sheet.insert(rule, item.group);
});
inserted.css[identifier] = true;
}
nextClassList.push(identifier);
}
});
}
if (typeof style === 'number') {
// fast and cachable
_injectRegisteredStyle(style);
var key = createCacheKey(style);
props = _resolveStyle(style, key);
} else if (!Array.isArray(style)) {
// resolve a plain RN style object
props = _resolveStyle(style);
} else {
// flatten the style array
// cache resolved props when all styles are registered
// otherwise fallback to resolving
var flatArray = flattenArray(style);
var isArrayOfNumbers = true;
var cacheKey = '';
for (var i = 0; i < flatArray.length; i++) {
var id = flatArray[i];
if (typeof id !== 'number') {
isArrayOfNumbers = false;
} else {
if (isArrayOfNumbers) {
cacheKey += id + '-';
}
_injectRegisteredStyle(id);
}
}
var _key = isArrayOfNumbers ? createCacheKey(cacheKey) : null;
props = _resolveStyle(flatArray, _key);
}
nextClassList.push.apply(nextClassList, props.classList);
var finalProps = {
className: classListToString(nextClassList),
classList: nextClassList
};
if (props.style) {
finalProps.style = props.style;
}
return finalProps;
}
/**
* Resolves a React Native style object
*/
function _resolveStyle(style, key) {
var doLeftAndRightSwapInRTL = I18nManager.doLeftAndRightSwapInRTL,
isRTL = I18nManager.isRTL;
var dir = isRTL ? doLeftAndRightSwapInRTL ? 'rtl' : 'rtlNoSwap' : 'ltr'; // faster: memoized
if (key != null && resolved[dir][key] != null) {
return resolved[dir][key];
}
var flatStyle = flattenStyle(style);
var localizedStyle = createCompileableStyle(i18nStyle(flatStyle)); // slower: convert style object to props and cache
var props = Object.keys(localizedStyle).sort().reduce(function (props, styleProp) {
var value = localizedStyle[styleProp];
if (value != null) {
var className = getClassName(styleProp, value);
if (className) {
props.classList.push(className);
} else {
// Certain properties and values are not transformed by 'createReactDOMStyle' as they
// require more complex transforms into multiple CSS rules. Here we assume that StyleManager
// can bind these styles to a className, and prevent them becoming invalid inline-styles.
if (styleProp === 'animationKeyframes' || styleProp === 'placeholderTextColor' || styleProp === 'pointerEvents' || styleProp === 'scrollbarWidth') {
var _atomic;
var a = atomic((_atomic = {}, _atomic[styleProp] = value, _atomic));
Object.keys(a).forEach(function (key) {
var _a$key = a[key],
identifier = _a$key.identifier,
rules = _a$key.rules;
props.classList.push(identifier);
rules.forEach(function (rule) {
sheet.insert(rule, STYLE_GROUPS.atomic);
});
});
} else {
if (!props.style) {
props.style = {};
} // 4x slower render
props.style[styleProp] = value;
}
}
}
return props;
}, {
classList: []
});
if (props.style) {
props.style = inline(props.style);
}
if (key != null) {
resolved[dir][key] = props;
}
return props;
}
return {
getStyleSheet: function getStyleSheet() {
var textContent = sheet.getTextContent(); // Reset state on the server so critical css is always the result
if (!canUseDOM) {
init();
}
return {
id: STYLE_ELEMENT_ID,
textContent: textContent
};
},
createCSS: function createCSS(rules, group) {
var result = {};
Object.keys(rules).forEach(function (name) {
var style = rules[name];
var compiled = classic(style, name);
Object.keys(compiled).forEach(function (key) {
var _compiled$key = compiled[key],
identifier = _compiled$key.identifier,
rules = _compiled$key.rules;
resolved.css[identifier] = {
group: group || STYLE_GROUPS.classic,
rules: rules
};
result[name] = identifier;
});
});
return result;
},
resolve: resolve,
sheet: sheet
};
}
/**
* Misc helpers
*/
var createCacheKey = function createCacheKey(id) {
var prefix = 'rn';
return prefix + "-" + id;
};
var classListToString = function classListToString(list) {
return list.join(' ').trim();
};