This commit is contained in:
Yamozha
2021-04-02 02:24:13 +03:00
parent c23950b545
commit 7256d79e2c
31493 changed files with 3036630 additions and 0 deletions

View File

@ -0,0 +1,57 @@
/**
* Copyright (c) Nicolas Gallagher.
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var emptyObject = {};
var objects = {};
var prefix = 'r';
var uniqueID = 1;
var createKey = function createKey(id) {
return prefix + "-" + id;
};
var ReactNativePropRegistry =
/*#__PURE__*/
function () {
function ReactNativePropRegistry() {}
ReactNativePropRegistry.register = function register(object) {
var id = uniqueID++;
if (process.env.NODE_ENV !== 'production') {
Object.freeze(object);
}
var key = createKey(id);
objects[key] = object;
return id;
};
ReactNativePropRegistry.getByID = function getByID(id) {
if (!id) {
// Used in the style={[condition && id]} pattern,
// we want it to be a no-op when the value is false or null
return emptyObject;
}
var key = createKey(id);
var object = objects[key];
if (!object) {
console.warn('Invalid style with id `' + id + '`. Skipping ...');
return emptyObject;
}
return object;
};
return ReactNativePropRegistry;
}();
export { ReactNativePropRegistry as default };

View File

@ -0,0 +1,63 @@
/**
* 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.
*
*
*/
import ReactNativePropRegistry from './ReactNativePropRegistry';
import flattenStyle from './flattenStyle';
var absoluteFillObject = {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0
};
var absoluteFill = ReactNativePropRegistry.register(absoluteFillObject);
var StyleSheet = {
absoluteFill: absoluteFill,
absoluteFillObject: absoluteFillObject,
compose: function compose(style1, style2) {
if (process.env.NODE_ENV !== 'production') {
/* eslint-disable prefer-rest-params */
var len = arguments.length;
if (len > 2) {
var readableStyles = Array.prototype.slice.call(arguments).map(function (a) {
return flattenStyle(a);
});
throw new Error("StyleSheet.compose() only accepts 2 arguments, received " + len + ": " + JSON.stringify(readableStyles));
}
/* eslint-enable prefer-rest-params */
}
if (style1 && style2) {
return [style1, style2];
} else {
return style1 || style2;
}
},
create: function create(styles) {
var result = {};
Object.keys(styles).forEach(function (key) {
if (process.env.NODE_ENV !== 'production') {
var validate = require('./validate');
var interopValidate = validate.default ? validate.default : validate;
interopValidate(key, styles);
}
var id = styles[key] && ReactNativePropRegistry.register(styles[key]);
result[key] = id;
});
return result;
},
flatten: flattenStyle,
// `hairlineWidth` is not implemented using screen density as browsers may
// round sub-pixel values down to `0`, causing the line not to be rendered.
hairlineWidth: 1
};
export default StyleSheet;

View File

@ -0,0 +1,311 @@
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
/**
* 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.
*
*
*/
import createReactDOMStyle from './createReactDOMStyle';
import hash from '../../vendor/hash';
import hyphenateStyleName from 'hyphenate-style-name';
import normalizeValueWithProperty from './normalizeValueWithProperty';
import prefixStyles, { prefixInlineStyles } from '../../modules/prefixStyles';
var cache = {
get: function get(property, value) {
if (cache[property] != null && cache[property].hasOwnProperty(value) && cache[property][value] != null) {
return cache[property][value];
}
},
set: function set(property, value, object) {
if (cache[property] == null) {
cache[property] = {};
}
return cache[property][value] = object;
}
};
/**
* Compile style to atomic CSS rules.
*/
export function atomic(style) {
return Object.keys(style).sort().reduce(function (acc, property) {
var value = style[property];
if (value != null) {
var valueString = stringifyValueWithProperty(value, property);
var cachedResult = cache.get(property, valueString);
if (cachedResult != null) {
var identifier = cachedResult.identifier;
acc[identifier] = cachedResult;
} else {
var _identifier = createIdentifier('r', property, value);
var rules = createAtomicRules(_identifier, property, value);
var _cachedResult = cache.set(property, valueString, {
property: property,
value: stringifyValueWithProperty(value, property),
identifier: _identifier,
rules: rules
});
acc[_identifier] = _cachedResult;
}
}
return acc;
}, {});
}
/**
* Compile simple style object to classic CSS rules.
* No support for 'placeholderTextColor', 'scrollbarWidth', or 'pointerEvents'.
*/
export function classic(style, name) {
var _ref;
var identifier = createIdentifier('css', name, style);
var animationKeyframes = style.animationKeyframes,
rest = _objectWithoutPropertiesLoose(style, ["animationKeyframes"]);
var rules = [];
var selector = "." + identifier;
var animationName;
if (animationKeyframes != null) {
var _processKeyframesValu = processKeyframesValue(animationKeyframes),
animationNames = _processKeyframesValu.animationNames,
keyframesRules = _processKeyframesValu.rules;
animationName = animationNames.join(',');
rules.push.apply(rules, keyframesRules);
}
var block = createDeclarationBlock(_objectSpread({}, rest, {
animationName: animationName
}));
rules.push("" + selector + block);
return _ref = {}, _ref[identifier] = {
identifier: identifier,
rules: rules
}, _ref;
}
/**
* Compile simple style object to inline DOM styles.
* No support for 'animationKeyframes', 'placeholderTextColor', 'scrollbarWidth', or 'pointerEvents'.
*/
export function inline(style) {
return prefixInlineStyles(createReactDOMStyle(style));
}
/**
* Create a value string that normalizes different input values with a common
* output.
*/
export function stringifyValueWithProperty(value, property) {
// e.g., 0 => '0px', 'black' => 'rgba(0,0,0,1)'
var normalizedValue = normalizeValueWithProperty(value, property);
return typeof normalizedValue !== 'string' ? JSON.stringify(normalizedValue || '') : normalizedValue;
}
/**
* Create the Atomic CSS rules needed for a given StyleSheet rule.
* Translates StyleSheet declarations to CSS.
*/
function createAtomicRules(identifier, property, value) {
var rules = [];
var selector = "." + identifier; // Handle non-standard properties and object values that require multiple
// CSS rules to be created.
switch (property) {
case 'animationKeyframes':
{
var _processKeyframesValu2 = processKeyframesValue(value),
animationNames = _processKeyframesValu2.animationNames,
keyframesRules = _processKeyframesValu2.rules;
var block = createDeclarationBlock({
animationName: animationNames.join(',')
});
rules.push.apply(rules, ["" + selector + block].concat(keyframesRules));
break;
}
// Equivalent to using '::placeholder'
case 'placeholderTextColor':
{
var _block = createDeclarationBlock({
color: value,
opacity: 1
});
rules.push(selector + "::-webkit-input-placeholder" + _block, selector + "::-moz-placeholder" + _block, selector + ":-ms-input-placeholder" + _block, selector + "::placeholder" + _block);
break;
}
// Polyfill for additional 'pointer-events' values
// See d13f78622b233a0afc0c7a200c0a0792c8ca9e58
case 'pointerEvents':
{
var _createDeclarationBlo3;
var finalValue = value;
if (value === 'auto' || value === 'box-only') {
finalValue = 'auto!important';
if (value === 'box-only') {
var _createDeclarationBlo;
var _block3 = createDeclarationBlock((_createDeclarationBlo = {}, _createDeclarationBlo[property] = 'none', _createDeclarationBlo));
rules.push(selector + ">*" + _block3);
}
} else if (value === 'none' || value === 'box-none') {
finalValue = 'none!important';
if (value === 'box-none') {
var _createDeclarationBlo2;
var _block4 = createDeclarationBlock((_createDeclarationBlo2 = {}, _createDeclarationBlo2[property] = 'auto', _createDeclarationBlo2));
rules.push(selector + ">*" + _block4);
}
}
var _block2 = createDeclarationBlock((_createDeclarationBlo3 = {}, _createDeclarationBlo3[property] = finalValue, _createDeclarationBlo3));
rules.push("" + selector + _block2);
break;
}
// Polyfill for draft spec
// https://drafts.csswg.org/css-scrollbars-1/
case 'scrollbarWidth':
{
var _createDeclarationBlo4;
if (value === 'none') {
rules.push(selector + "::-webkit-scrollbar{display:none}");
}
var _block5 = createDeclarationBlock((_createDeclarationBlo4 = {}, _createDeclarationBlo4[property] = value, _createDeclarationBlo4));
rules.push("" + selector + _block5);
break;
}
default:
{
var _createDeclarationBlo5;
var _block6 = createDeclarationBlock((_createDeclarationBlo5 = {}, _createDeclarationBlo5[property] = value, _createDeclarationBlo5));
rules.push("" + selector + _block6);
break;
}
}
return rules;
}
/**
* Creates a CSS declaration block from a StyleSheet object.
*/
function createDeclarationBlock(style) {
var domStyle = prefixStyles(createReactDOMStyle(style));
var declarationsString = Object.keys(domStyle).map(function (property) {
var value = domStyle[property];
var prop = hyphenateStyleName(property); // The prefixer may return an array of values:
// { display: [ '-webkit-flex', 'flex' ] }
// to represent "fallback" declarations
// { display: -webkit-flex; display: flex; }
if (Array.isArray(value)) {
return value.map(function (v) {
return prop + ":" + v;
}).join(';');
} else {
return prop + ":" + value;
}
}) // Once properties are hyphenated, this will put the vendor
// prefixed and short-form properties first in the list.
.sort().join(';');
return "{" + declarationsString + ";}";
}
/**
* An identifier is associated with a unique set of styles.
*/
function createIdentifier(prefix, name, value) {
var hashedString = hash(name + stringifyValueWithProperty(value, name));
return process.env.NODE_ENV !== 'production' ? prefix + "-" + name + "-" + hashedString : prefix + "-" + hashedString;
}
/**
* Create individual CSS keyframes rules.
*/
function createKeyframes(keyframes) {
var prefixes = ['-webkit-', ''];
var identifier = createIdentifier('r', 'animation', keyframes);
var steps = '{' + Object.keys(keyframes).map(function (stepName) {
var rule = keyframes[stepName];
var block = createDeclarationBlock(rule);
return "" + stepName + block;
}).join('') + '}';
var rules = prefixes.map(function (prefix) {
return "@" + prefix + "keyframes " + identifier + steps;
});
return {
identifier: identifier,
rules: rules
};
}
/**
* Create CSS keyframes rules and names from a StyleSheet keyframes object.
*/
function processKeyframesValue(keyframesValue) {
if (typeof keyframesValue === 'number') {
throw new Error("Invalid CSS keyframes type: " + typeof keyframesValue);
}
var animationNames = [];
var rules = [];
var value = Array.isArray(keyframesValue) ? keyframesValue : [keyframesValue];
value.forEach(function (keyframes) {
if (typeof keyframes === 'string') {
// Support external animation libraries (identifiers only)
animationNames.push(keyframes);
} else {
// Create rules for each of the keyframes
var _createKeyframes = createKeyframes(keyframes),
identifier = _createKeyframes.identifier,
keyframesRules = _createKeyframes.rules;
animationNames.push(identifier);
rules.push.apply(rules, keyframesRules);
}
});
return {
animationNames: animationNames,
rules: rules
};
}

View File

@ -0,0 +1,48 @@
/**
* 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.
*
*
*/
export var STYLE_ELEMENT_ID = 'react-native-stylesheet';
export var STYLE_GROUPS = {
reset: 0,
modality: 0.1,
classicReset: 0.5,
classic: 1,
atomic: 2.2,
custom: {
borderColor: 2,
borderRadius: 2,
borderStyle: 2,
borderWidth: 2,
display: 2,
flex: 2,
margin: 2,
overflow: 2,
overscrollBehavior: 2,
padding: 2,
marginHorizontal: 2.1,
marginVertical: 2.1,
paddingHorizontal: 2.1,
paddingVertical: 2.1
}
};
export var STYLE_SHORT_FORM_EXPANSIONS = {
borderColor: ['borderTopColor', 'borderRightColor', 'borderBottomColor', 'borderLeftColor'],
borderRadius: ['borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomRightRadius', 'borderBottomLeftRadius'],
borderStyle: ['borderTopStyle', 'borderRightStyle', 'borderBottomStyle', 'borderLeftStyle'],
borderWidth: ['borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth'],
margin: ['marginTop', 'marginRight', 'marginBottom', 'marginLeft'],
marginHorizontal: ['marginRight', 'marginLeft'],
marginVertical: ['marginTop', 'marginBottom'],
overflow: ['overflowX', 'overflowY'],
overscrollBehavior: ['overscrollBehaviorX', 'overscrollBehaviorY'],
padding: ['paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft'],
paddingHorizontal: ['paddingRight', 'paddingLeft'],
paddingVertical: ['paddingTop', 'paddingBottom']
};
export var MONOSPACE_FONT_STACK = 'monospace,monospace';
export var SYSTEM_FONT_STACK = '-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif';

View File

@ -0,0 +1,34 @@
/**
* 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.
*
*
*/
import { canUseDOM } from 'fbjs/lib/ExecutionEnvironment'; // $FlowFixMe: HTMLStyleElement is incorrectly typed - https://github.com/facebook/flow/issues/2696
export default function createCSSStyleSheet(id) {
if (canUseDOM) {
var element = document.getElementById(id);
if (element != null) {
// $FlowFixMe: HTMLElement is incorrectly typed
return element.sheet;
} else {
var _element = document.createElement('style');
_element.setAttribute('id', id);
var head = document.head;
if (head) {
head.insertBefore(_element, head.firstChild);
}
return _element.sheet;
}
} else {
return null;
}
}

View File

@ -0,0 +1,68 @@
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
/**
* 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.
*
*
*/
import normalizeValueWithProperty from './normalizeValueWithProperty';
import resolveShadowValue from './resolveShadowValue';
var defaultOffset = {
height: 0,
width: 0
};
function boxShadowReducer(resolvedStyle, style) {
var boxShadow = style.boxShadow;
var shadow = resolveShadowValue(style);
if (shadow != null) {
resolvedStyle.boxShadow = boxShadow ? boxShadow + ", " + shadow : shadow;
}
}
function textShadowReducer(resolvedStyle, style) {
var textShadowColor = style.textShadowColor,
textShadowOffset = style.textShadowOffset,
textShadowRadius = style.textShadowRadius;
var _ref = textShadowOffset || defaultOffset,
height = _ref.height,
width = _ref.width;
var radius = textShadowRadius || 0;
var offsetX = normalizeValueWithProperty(width);
var offsetY = normalizeValueWithProperty(height);
var blurRadius = normalizeValueWithProperty(radius);
var color = normalizeValueWithProperty(textShadowColor, 'textShadowColor');
if (color && (height !== 0 || width !== 0 || radius !== 0) && offsetX != null && offsetY != null && blurRadius != null) {
resolvedStyle.textShadow = offsetX + " " + offsetY + " " + blurRadius + " " + color;
}
}
var createCompileableStyle = function createCompileableStyle(styles) {
var shadowColor = styles.shadowColor,
shadowOffset = styles.shadowOffset,
shadowOpacity = styles.shadowOpacity,
shadowRadius = styles.shadowRadius,
textShadowColor = styles.textShadowColor,
textShadowOffset = styles.textShadowOffset,
textShadowRadius = styles.textShadowRadius,
nextStyles = _objectWithoutPropertiesLoose(styles, ["shadowColor", "shadowOffset", "shadowOpacity", "shadowRadius", "textShadowColor", "textShadowOffset", "textShadowRadius"]);
if (shadowColor != null || shadowOffset != null || shadowOpacity != null || shadowRadius != null) {
boxShadowReducer(nextStyles, styles);
}
if (textShadowColor != null || textShadowOffset != null || textShadowRadius != null) {
textShadowReducer(nextStyles, styles);
}
return nextStyles;
};
export default createCompileableStyle;

View File

@ -0,0 +1,170 @@
/**
* 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.
*
*
*/
var slice = Array.prototype.slice;
/**
* Order-based insertion of CSS.
*
* Each rule is associated with a numerically defined group.
* Groups are ordered within the style sheet according to their number, with the
* lowest first.
*
* Groups are implemented using marker rules. The selector of the first rule of
* each group is used only to encode the group number for hydration. An
* alternative implementation could rely on CSSMediaRule, allowing groups to be
* treated as a sub-sheet, but the Edge implementation of CSSMediaRule is
* broken.
* https://developer.mozilla.org/en-US/docs/Web/API/CSSMediaRule
* https://gist.github.com/necolas/aa0c37846ad6bd3b05b727b959e82674
*/
export default function createOrderedCSSStyleSheet(sheet) {
var groups = {};
var selectors = {};
/**
* Hydrate approximate record from any existing rules in the sheet.
*/
if (sheet != null) {
var group;
slice.call(sheet.cssRules).forEach(function (cssRule, i) {
var cssText = cssRule.cssText; // Create record of existing selectors and rules
if (cssText.indexOf('stylesheet-group') > -1) {
group = decodeGroupRule(cssRule);
groups[group] = {
start: i,
rules: [cssText]
};
} else {
var selectorText = getSelectorText(cssText);
if (selectorText != null) {
selectors[selectorText] = true;
groups[group].rules.push(cssText);
}
}
});
}
function sheetInsert(sheet, group, text) {
var orderedGroups = getOrderedGroups(groups);
var groupIndex = orderedGroups.indexOf(group);
var nextGroupIndex = groupIndex + 1;
var nextGroup = orderedGroups[nextGroupIndex]; // Insert rule before the next group, or at the end of the stylesheet
var position = nextGroup != null && groups[nextGroup].start != null ? groups[nextGroup].start : sheet.cssRules.length;
var isInserted = insertRuleAt(sheet, text, position);
if (isInserted) {
// Set the starting index of the new group
if (groups[group].start == null) {
groups[group].start = position;
} // Increment the starting index of all subsequent groups
for (var i = nextGroupIndex; i < orderedGroups.length; i += 1) {
var groupNumber = orderedGroups[i];
var previousStart = groups[groupNumber].start;
groups[groupNumber].start = previousStart + 1;
}
}
return isInserted;
}
var OrderedCSSStyleSheet = {
/**
* The textContent of the style sheet.
*/
getTextContent: function getTextContent() {
return getOrderedGroups(groups).map(function (group) {
var rules = groups[group].rules;
return rules.join('\n');
}).join('\n');
},
/**
* Insert a rule into the style sheet
*/
insert: function insert(cssText, groupValue) {
var group = Number(groupValue); // Create a new group.
if (groups[group] == null) {
var markerRule = encodeGroupRule(group); // Create the internal record.
groups[group] = {
start: null,
rules: [markerRule]
}; // Update CSSOM.
if (sheet != null) {
sheetInsert(sheet, group, markerRule);
}
} // selectorText is more reliable than cssText for insertion checks. The
// browser excludes vendor-prefixed properties and rewrites certain values
// making cssText more likely to be different from what was inserted.
var selectorText = getSelectorText(cssText);
if (selectorText != null && selectors[selectorText] == null) {
// Update the internal records.
selectors[selectorText] = true;
groups[group].rules.push(cssText); // Update CSSOM.
if (sheet != null) {
var isInserted = sheetInsert(sheet, group, cssText);
if (!isInserted) {
// Revert internal record change if a rule was rejected (e.g.,
// unrecognized pseudo-selector)
groups[group].rules.pop();
}
}
}
}
};
return OrderedCSSStyleSheet;
}
/**
* Helper functions
*/
function encodeGroupRule(group) {
return "[stylesheet-group=\"" + group + "\"]{}";
}
function decodeGroupRule(cssRule) {
return Number(cssRule.selectorText.split(/["']/)[1]);
}
function getOrderedGroups(obj) {
return Object.keys(obj).map(Number).sort(function (a, b) {
return a > b ? 1 : -1;
});
}
var pattern = /\s*([,])\s*/g;
function getSelectorText(cssText) {
var selector = cssText.split('{')[0].trim();
return selector !== '' ? selector.replace(pattern, '$1') : null;
}
function insertRuleAt(root, cssText, position) {
try {
// $FlowFixMe: Flow is missing CSSOM types needed to type 'root'.
root.insertRule(cssText, position);
return true;
} catch (e) {
// JSDOM doesn't support `CSSSMediaRule#insertRule`.
// Also ignore errors that occur from attempting to insert vendor-prefixed selectors.
return false;
}
}

View File

@ -0,0 +1,199 @@
/**
* 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.
*
*
*/
import { canUseDOM } from 'fbjs/lib/ExecutionEnvironment';
import { MONOSPACE_FONT_STACK, SYSTEM_FONT_STACK, STYLE_SHORT_FORM_EXPANSIONS } from './constants';
import normalizeValueWithProperty from './normalizeValueWithProperty';
/**
* The browser implements the CSS cascade, where the order of properties is a
* factor in determining which styles to paint. React Native is different. It
* gives giving precedence to the more specific style property. For example,
* the value of `paddingTop` takes precedence over that of `padding`.
*
* This module creates mutally exclusive style declarations by expanding all of
* React Native's supported shortform properties (e.g. `padding`) to their
* longfrom equivalents.
*/
var emptyObject = {};
var supportsCSS3TextDecoration = !canUseDOM || window.CSS != null && window.CSS.supports != null && (window.CSS.supports('text-decoration-line', 'none') || window.CSS.supports('-webkit-text-decoration-line', 'none'));
/**
* Transform
*/
// { scale: 2 } => 'scale(2)'
// { translateX: 20 } => 'translateX(20px)'
var mapTransform = function mapTransform(transform) {
var type = Object.keys(transform)[0];
var value = normalizeValueWithProperty(transform[type], type);
return type + "(" + value + ")";
}; // [1,2,3,4,5,6] => 'matrix3d(1,2,3,4,5,6)'
var convertTransformMatrix = function convertTransformMatrix(transformMatrix) {
var matrix = transformMatrix.join(',');
return "matrix3d(" + matrix + ")";
};
var resolveTransform = function resolveTransform(resolvedStyle, style) {
var transform = style.transform;
if (Array.isArray(style.transform)) {
transform = style.transform.map(mapTransform).join(' ');
} else if (style.transformMatrix) {
transform = convertTransformMatrix(style.transformMatrix);
}
resolvedStyle.transform = transform;
};
/**
* Reducer
*/
var createReactDOMStyle = function createReactDOMStyle(style) {
if (!style) {
return emptyObject;
}
var resolvedStyle = {};
Object.keys(style).sort().forEach(function (prop) {
var value = normalizeValueWithProperty(style[prop], prop); // Ignore everything else with a null value
if (value == null) {
return;
}
switch (prop) {
// Ignore some React Native styles
case 'aspectRatio':
case 'elevation':
case 'overlayColor':
case 'resizeMode':
case 'tintColor':
{
break;
}
// TODO: remove once this issue is fixed
// https://github.com/rofrischmann/inline-style-prefixer/issues/159
case 'backgroundClip':
{
if (value === 'text') {
resolvedStyle.backgroundClip = value;
resolvedStyle.WebkitBackgroundClip = value;
}
break;
}
// The 'flex' property value in React Native must be a positive integer,
// 0, or -1.
case 'flex':
{
if (value > 0) {
resolvedStyle.flexGrow = value;
resolvedStyle.flexShrink = 1;
resolvedStyle.flexBasis = '0%';
} else if (value === 0) {
resolvedStyle.flexGrow = 0;
resolvedStyle.flexShrink = 0;
resolvedStyle.flexBasis = '0%';
} else if (value === -1) {
resolvedStyle.flexGrow = 0;
resolvedStyle.flexShrink = 1;
resolvedStyle.flexBasis = 'auto';
}
break;
}
case 'font':
{
resolvedStyle[prop] = value.replace('System', SYSTEM_FONT_STACK);
break;
}
case 'fontFamily':
{
if (value.indexOf('System') > -1) {
var stack = value.split(/,\s*/);
stack[stack.indexOf('System')] = SYSTEM_FONT_STACK;
resolvedStyle[prop] = stack.join(',');
} else if (value === 'monospace') {
resolvedStyle[prop] = MONOSPACE_FONT_STACK;
} else {
resolvedStyle[prop] = value;
}
break;
}
case 'fontVariant':
{
if (Array.isArray(value) && value.length > 0) {
resolvedStyle.fontVariant = value.join(' ');
}
break;
}
case 'textAlignVertical':
{
resolvedStyle.verticalAlign = value === 'center' ? 'middle' : value;
break;
}
case 'textDecorationLine':
{
// use 'text-decoration' for browsers that only support CSS2
// text-decoration (e.g., IE, Edge)
if (!supportsCSS3TextDecoration) {
resolvedStyle.textDecoration = value;
} else {
resolvedStyle.textDecorationLine = value;
}
break;
}
case 'transform':
case 'transformMatrix':
{
resolveTransform(resolvedStyle, style);
break;
}
case 'writingDirection':
{
resolvedStyle.direction = value;
break;
}
default:
{
var longFormProperties = STYLE_SHORT_FORM_EXPANSIONS[prop];
if (longFormProperties) {
longFormProperties.forEach(function (longForm, i) {
// The value of any longform property in the original styles takes
// precedence over the shortform's value.
if (typeof style[longForm] === 'undefined') {
resolvedStyle[longForm] = value;
}
});
} else {
resolvedStyle[prop] = Array.isArray(value) ? value.join(',') : value;
}
}
}
});
return resolvedStyle;
};
export default createReactDOMStyle;

View File

@ -0,0 +1,282 @@
/**
* 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();
};

View File

@ -0,0 +1,24 @@
/**
* 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.
*
*
*/
import styleResolver from './styleResolver';
/**
* A simple (and dangerous) CSS system.
* The order of CSS rule insertion is not guaranteed.
* Avoiding combining 2 or more classes that modify the same property.
*/
var css = {
/**
* const classes = css.create({ base: {}, extra: {} })
*/
create: function create(rules, group) {
return styleResolver.createCSS(rules, group);
}
};
export default css;

View File

@ -0,0 +1,50 @@
/**
* Copyright (c) Nicolas Gallagher.
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
import ReactNativePropRegistry from './ReactNativePropRegistry';
import invariant from 'fbjs/lib/invariant';
function getStyle(style) {
if (typeof style === 'number') {
return ReactNativePropRegistry.getByID(style);
}
return style;
}
function flattenStyle(style) {
if (!style) {
return undefined;
}
if (process.env.NODE_ENV !== 'production') {
invariant(style !== true, 'style may be false but not true');
}
if (!Array.isArray(style)) {
return getStyle(style);
}
var result = {};
for (var i = 0, styleLength = style.length; i < styleLength; ++i) {
var computedStyle = flattenStyle(style[i]);
if (computedStyle) {
for (var key in computedStyle) {
var value = computedStyle[key];
result[key] = value;
}
}
}
return result;
}
export default flattenStyle;

View File

@ -0,0 +1,143 @@
/**
* 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.
*
*
*/
import I18nManager from '../I18nManager';
import multiplyStyleLengthValue from '../../modules/multiplyStyleLengthValue';
var emptyObject = {};
var borderTopLeftRadius = 'borderTopLeftRadius';
var borderTopRightRadius = 'borderTopRightRadius';
var borderBottomLeftRadius = 'borderBottomLeftRadius';
var borderBottomRightRadius = 'borderBottomRightRadius';
var borderLeftColor = 'borderLeftColor';
var borderLeftStyle = 'borderLeftStyle';
var borderLeftWidth = 'borderLeftWidth';
var borderRightColor = 'borderRightColor';
var borderRightStyle = 'borderRightStyle';
var borderRightWidth = 'borderRightWidth';
var right = 'right';
var marginLeft = 'marginLeft';
var marginRight = 'marginRight';
var paddingLeft = 'paddingLeft';
var paddingRight = 'paddingRight';
var left = 'left'; // Map of LTR property names to their BiDi equivalent.
var PROPERTIES_FLIP = {
borderTopLeftRadius: borderTopRightRadius,
borderTopRightRadius: borderTopLeftRadius,
borderBottomLeftRadius: borderBottomRightRadius,
borderBottomRightRadius: borderBottomLeftRadius,
borderLeftColor: borderRightColor,
borderLeftStyle: borderRightStyle,
borderLeftWidth: borderRightWidth,
borderRightColor: borderLeftColor,
borderRightStyle: borderLeftStyle,
borderRightWidth: borderLeftWidth,
left: right,
marginLeft: marginRight,
marginRight: marginLeft,
paddingLeft: paddingRight,
paddingRight: paddingLeft,
right: left
}; // Map of I18N property names to their LTR equivalent.
var PROPERTIES_I18N = {
borderTopStartRadius: borderTopLeftRadius,
borderTopEndRadius: borderTopRightRadius,
borderBottomStartRadius: borderBottomLeftRadius,
borderBottomEndRadius: borderBottomRightRadius,
borderStartColor: borderLeftColor,
borderStartStyle: borderLeftStyle,
borderStartWidth: borderLeftWidth,
borderEndColor: borderRightColor,
borderEndStyle: borderRightStyle,
borderEndWidth: borderRightWidth,
end: right,
marginStart: marginLeft,
marginEnd: marginRight,
paddingStart: paddingLeft,
paddingEnd: paddingRight,
start: left
};
var PROPERTIES_VALUE = {
clear: true,
float: true,
textAlign: true
}; // Invert the sign of a numeric-like value
var additiveInverse = function additiveInverse(value) {
return multiplyStyleLengthValue(value, -1);
};
var i18nStyle = function i18nStyle(originalStyle) {
var doLeftAndRightSwapInRTL = I18nManager.doLeftAndRightSwapInRTL,
isRTL = I18nManager.isRTL;
var style = originalStyle || emptyObject;
var frozenProps = {};
var nextStyle = {};
for (var originalProp in style) {
if (!Object.prototype.hasOwnProperty.call(style, originalProp)) {
continue;
}
var originalValue = style[originalProp];
var prop = originalProp;
var value = originalValue; // BiDi flip properties
if (PROPERTIES_I18N.hasOwnProperty(originalProp)) {
// convert start/end
var convertedProp = PROPERTIES_I18N[originalProp];
prop = isRTL ? PROPERTIES_FLIP[convertedProp] : convertedProp;
} else if (isRTL && doLeftAndRightSwapInRTL && PROPERTIES_FLIP[originalProp]) {
prop = PROPERTIES_FLIP[originalProp];
} // BiDi flip values
if (PROPERTIES_VALUE.hasOwnProperty(originalProp)) {
if (originalValue === 'start') {
value = isRTL ? 'right' : 'left';
} else if (originalValue === 'end') {
value = isRTL ? 'left' : 'right';
} else if (isRTL && doLeftAndRightSwapInRTL) {
if (originalValue === 'left') {
value = 'right';
} else if (originalValue === 'right') {
value = 'left';
}
}
} // BiDi flip transitionProperty value
if (prop === 'transitionProperty') {
// BiDi flip properties
if (PROPERTIES_I18N.hasOwnProperty(value)) {
// convert start/end
var convertedValue = PROPERTIES_I18N[originalValue];
value = isRTL ? PROPERTIES_FLIP[convertedValue] : convertedValue;
} else if (isRTL && doLeftAndRightSwapInRTL && PROPERTIES_FLIP[originalValue]) {
value = PROPERTIES_FLIP[originalValue];
}
} // Create finalized style
if (isRTL && prop === 'textShadowOffset') {
nextStyle[prop] = value;
nextStyle[prop].width = additiveInverse(value.width);
} else if (!frozenProps[prop]) {
nextStyle[prop] = value;
}
if (PROPERTIES_I18N[originalProp]) {
frozenProps[prop] = true;
}
}
return nextStyle;
};
export default i18nStyle;

View File

@ -0,0 +1,16 @@
/**
* 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.
*
*
*/
import { canUseDOM } from 'fbjs/lib/ExecutionEnvironment';
import StyleSheet from './StyleSheet'; // allow original component styles to be inspected in React Dev Tools
if (canUseDOM && window.__REACT_DEVTOOLS_GLOBAL_HOOK__) {
window.__REACT_DEVTOOLS_GLOBAL_HOOK__.resolveRNStyle = StyleSheet.flatten;
}
export default StyleSheet;

View File

@ -0,0 +1,12 @@
/**
* 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.
*
*
*/
var resets = [// minimal top-level reset
'html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0);}', 'body{margin:0;}', // minimal form pseudo-element reset
'button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}', 'input::-webkit-inner-spin-button,input::-webkit-outer-spin-button,' + 'input::-webkit-search-cancel-button,input::-webkit-search-decoration,' + 'input::-webkit-search-results-button,input::-webkit-search-results-decoration{display:none;}'];
export default resets;

View File

@ -0,0 +1,280 @@
/**
* Adapts focus styles based on the user's active input modality (i.e., how
* they are interacting with the UI right now).
*
* Focus styles are only relevant when using the keyboard to interact with the
* page. If we only show the focus ring when relevant, we can avoid user
* confusion without compromising accessibility.
*
* The script uses two heuristics to determine whether the keyboard is being used:
*
* 1. a keydown event occurred immediately before a focus event;
* 2. a focus event happened on an element which requires keyboard interaction (e.g., a text field);
*
* This software or document includes material copied from or derived from https://github.com/WICG/focus-visible.
* Copyright © 2018 W3C® (MIT, ERCIM, Keio, Beihang).
* W3C Software Notice and License: https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
*
*
*/
import { canUseDOM } from 'fbjs/lib/ExecutionEnvironment';
var focusVisibleAttributeName = 'data-focusvisible-polyfill';
var rule = ":focus:not([" + focusVisibleAttributeName + "]){outline: none;}";
var modality = function modality(insertRule) {
insertRule(rule);
if (!canUseDOM) {
return;
}
var hadKeyboardEvent = true;
var hadFocusVisibleRecently = false;
var hadFocusVisibleRecentlyTimeout = null;
var inputTypesWhitelist = {
text: true,
search: true,
url: true,
tel: true,
email: true,
password: true,
number: true,
date: true,
month: true,
week: true,
time: true,
datetime: true,
'datetime-local': true
};
/**
* Helper function for legacy browsers and iframes which sometimes focus
* elements like document, body, and non-interactive SVG.
*/
function isValidFocusTarget(el) {
if (el && el !== document && el.nodeName !== 'HTML' && el.nodeName !== 'BODY' && 'classList' in el && 'contains' in el.classList) {
return true;
}
return false;
}
/**
* Computes whether the given element should automatically trigger the
* `focus-visible` attribute being added, i.e. whether it should always match
* `:focus-visible` when focused.
*/
function focusTriggersKeyboardModality(el) {
var type = el.type;
var tagName = el.tagName;
var isReadOnly = el.readOnly;
if (tagName === 'INPUT' && inputTypesWhitelist[type] && !isReadOnly) {
return true;
}
if (tagName === 'TEXTAREA' && !isReadOnly) {
return true;
}
if (el.isContentEditable) {
return true;
}
return false;
}
/**
* Add the `focus-visible` attribute to the given element if it was not added by
* the author.
*/
function addFocusVisibleAttribute(el) {
if (el.hasAttribute(focusVisibleAttributeName)) {
return;
}
el.setAttribute(focusVisibleAttributeName, true);
}
/**
* Remove the `focus-visible` attribute from the given element if it was not
* originally added by the author.
*/
function removeFocusVisibleAttribute(el) {
el.removeAttribute(focusVisibleAttributeName);
}
/**
* Remove the `focus-visible` attribute from all elements in the document.
*/
function removeAllFocusVisibleAttributes() {
var list = document.querySelectorAll("[" + focusVisibleAttributeName + "]");
for (var i = 0; i < list.length; i += 1) {
removeFocusVisibleAttribute(list[i]);
}
}
/**
* Treat `keydown` as a signal that the user is in keyboard modality.
* Apply `focus-visible` to any current active element and keep track
* of our keyboard modality state with `hadKeyboardEvent`.
*/
function onKeyDown(e) {
if (e.key !== 'Tab' && (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey)) {
return;
}
if (isValidFocusTarget(document.activeElement)) {
addFocusVisibleAttribute(document.activeElement);
}
hadKeyboardEvent = true;
}
/**
* If at any point a user clicks with a pointing device, ensure that we change
* the modality away from keyboard.
* This avoids the situation where a user presses a key on an already focused
* element, and then clicks on a different element, focusing it with a
* pointing device, while we still think we're in keyboard modality.
* It also avoids the situation where a user presses on an element within a
* previously keyboard-focused element (i.e., `e.target` is not the previously
* focused element, but one of its descendants) and we need to remove the
* focus ring because a `blur` event doesn't occur.
*/
function onPointerDown(e) {
if (hadKeyboardEvent === true) {
removeAllFocusVisibleAttributes();
}
hadKeyboardEvent = false;
}
/**
* On `focus`, add the `focus-visible` attribute to the target if:
* - the target received focus as a result of keyboard navigation, or
* - the event target is an element that will likely require interaction
* via the keyboard (e.g. a text box)
*/
function onFocus(e) {
// Prevent IE from focusing the document or HTML element.
if (!isValidFocusTarget(e.target)) {
return;
}
if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) {
addFocusVisibleAttribute(e.target);
}
}
/**
* On `blur`, remove the `focus-visible` attribute from the target.
*/
function onBlur(e) {
if (!isValidFocusTarget(e.target)) {
return;
}
if (e.target.hasAttribute(focusVisibleAttributeName)) {
// To detect a tab/window switch, we look for a blur event followed
// rapidly by a visibility change.
// If we don't see a visibility change within 100ms, it's probably a
// regular focus change.
hadFocusVisibleRecently = true;
window.clearTimeout(hadFocusVisibleRecentlyTimeout);
hadFocusVisibleRecentlyTimeout = window.setTimeout(function () {
hadFocusVisibleRecently = false;
window.clearTimeout(hadFocusVisibleRecentlyTimeout);
}, 100);
removeFocusVisibleAttribute(e.target);
}
}
/**
* If the user changes tabs, keep track of whether or not the previously
* focused element had the focus-visible attribute.
*/
function onVisibilityChange(e) {
if (document.visibilityState === 'hidden') {
// If the tab becomes active again, the browser will handle calling focus
// on the element (Safari actually calls it twice).
// If this tab change caused a blur on an element with focus-visible,
// re-apply the attribute when the user switches back to the tab.
if (hadFocusVisibleRecently) {
hadKeyboardEvent = true;
}
addInitialPointerMoveListeners();
}
}
/**
* Add a group of listeners to detect usage of any pointing devices.
* These listeners will be added when the polyfill first loads, and anytime
* the window is blurred, so that they are active when the window regains
* focus.
*/
function addInitialPointerMoveListeners() {
document.addEventListener('mousemove', onInitialPointerMove);
document.addEventListener('mousedown', onInitialPointerMove);
document.addEventListener('mouseup', onInitialPointerMove);
document.addEventListener('pointermove', onInitialPointerMove);
document.addEventListener('pointerdown', onInitialPointerMove);
document.addEventListener('pointerup', onInitialPointerMove);
document.addEventListener('touchmove', onInitialPointerMove);
document.addEventListener('touchstart', onInitialPointerMove);
document.addEventListener('touchend', onInitialPointerMove);
}
function removeInitialPointerMoveListeners() {
document.removeEventListener('mousemove', onInitialPointerMove);
document.removeEventListener('mousedown', onInitialPointerMove);
document.removeEventListener('mouseup', onInitialPointerMove);
document.removeEventListener('pointermove', onInitialPointerMove);
document.removeEventListener('pointerdown', onInitialPointerMove);
document.removeEventListener('pointerup', onInitialPointerMove);
document.removeEventListener('touchmove', onInitialPointerMove);
document.removeEventListener('touchstart', onInitialPointerMove);
document.removeEventListener('touchend', onInitialPointerMove);
}
/**
* When the polfyill first loads, assume the user is in keyboard modality.
* If any event is received from a pointing device (e.g. mouse, pointer,
* touch), turn off keyboard modality.
* This accounts for situations where focus enters the page from the URL bar.
*/
function onInitialPointerMove(e) {
// Work around a Safari quirk that fires a mousemove on <html> whenever the
// window blurs, even if you're tabbing out of the page. ¯\_(ツ)_/¯
if (e.target.nodeName === 'HTML') {
return;
}
hadKeyboardEvent = false;
removeInitialPointerMoveListeners();
}
document.addEventListener('keydown', onKeyDown, true);
document.addEventListener('mousedown', onPointerDown, true);
document.addEventListener('pointerdown', onPointerDown, true);
document.addEventListener('touchstart', onPointerDown, true);
document.addEventListener('focus', onFocus, true);
document.addEventListener('blur', onBlur, true);
document.addEventListener('visibilitychange', onVisibilityChange, true);
addInitialPointerMoveListeners();
};
export default modality;

View File

@ -0,0 +1,33 @@
/**
* 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.
*
*
*/
import unitlessNumbers from '../../modules/unitlessNumbers';
import normalizeColor from '../../modules/normalizeColor';
var colorProps = {
backgroundColor: true,
borderColor: true,
borderTopColor: true,
borderRightColor: true,
borderBottomColor: true,
borderLeftColor: true,
color: true,
shadowColor: true,
textDecorationColor: true,
textShadowColor: true
};
export default function normalizeValueWithProperty(value, property) {
var returnValue = value;
if ((property == null || !unitlessNumbers[property]) && typeof value === 'number') {
returnValue = value + "px";
} else if (property != null && colorProps[property]) {
returnValue = normalizeColor(value);
}
return returnValue;
}

View File

@ -0,0 +1,36 @@
/**
* 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.
*
*
*/
import normalizeColor from '../../modules/normalizeColor';
import normalizeValueWithProperty from './normalizeValueWithProperty';
var defaultOffset = {
height: 0,
width: 0
};
var resolveShadowValue = function resolveShadowValue(style) {
var shadowColor = style.shadowColor,
shadowOffset = style.shadowOffset,
shadowOpacity = style.shadowOpacity,
shadowRadius = style.shadowRadius;
var _ref = shadowOffset || defaultOffset,
height = _ref.height,
width = _ref.width;
var offsetX = normalizeValueWithProperty(width);
var offsetY = normalizeValueWithProperty(height);
var blurRadius = normalizeValueWithProperty(shadowRadius || 0);
var color = normalizeColor(shadowColor || 'black', shadowOpacity);
if (color != null && offsetX != null && offsetY != null && blurRadius != null) {
return offsetX + " " + offsetY + " " + blurRadius + " " + color;
}
};
export default resolveShadowValue;

View File

@ -0,0 +1,11 @@
/**
* 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.
*
*
*/
import createStyleResolver from './createStyleResolver';
var styleResolver = createStyleResolver();
export default styleResolver;

View File

@ -0,0 +1,69 @@
/**
* 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.
*
*
*/
import warning from 'fbjs/lib/warning';
var invalidShortforms = {
background: true,
borderBottom: true,
borderLeft: true,
borderRight: true,
borderTop: true,
font: true,
grid: true,
outline: true,
textDecoration: true
};
function error(message) {
warning(false, message);
}
export default function validate(key, styles) {
var obj = styles[key];
for (var k in obj) {
var prop = k.trim();
var value = obj[prop];
var isInvalid = false;
if (value === null) {
continue;
}
if (typeof value === 'string' && value.indexOf('!important') > -1) {
error("Invalid style declaration \"" + prop + ":" + value + "\". Values cannot include \"!important\"");
isInvalid = true;
} else {
var suggestion = '';
if (prop === 'animation' || prop === 'animationName') {
suggestion = 'Did you mean "animationKeyframes"?'; // } else if (prop === 'boxShadow') {
// suggestion = 'Did you mean "shadow{Color,Offset,Opacity,Radius}"?';
isInvalid = true;
} else if (prop === 'direction') {
suggestion = 'Did you mean "writingDirection"?';
isInvalid = true;
} else if (prop === 'verticalAlign') {
suggestion = 'Did you mean "textAlignVertical"?';
isInvalid = true;
} else if (invalidShortforms[prop]) {
suggestion = 'Please use long-form properties.';
isInvalid = true;
}
if (suggestion !== '') {
error("Invalid style property of \"" + prop + "\". " + suggestion);
}
}
if (isInvalid) {
delete obj[k];
}
}
}