StyleSheetValidation.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /**
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. *
  7. * @format
  8. * @flow
  9. */
  10. 'use strict';
  11. const DeprecatedImageStylePropTypes = require('../DeprecatedPropTypes/DeprecatedImageStylePropTypes');
  12. const DeprecatedTextStylePropTypes = require('../DeprecatedPropTypes/DeprecatedTextStylePropTypes');
  13. const DeprecatedViewStylePropTypes = require('../DeprecatedPropTypes/DeprecatedViewStylePropTypes');
  14. const invariant = require('invariant');
  15. // Hardcoded because this is a legit case but we don't want to load it from
  16. // a private API. We might likely want to unify style sheet creation with how it
  17. // is done in the DOM so this might move into React. I know what I'm doing so
  18. // plz don't fire me.
  19. const ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
  20. class StyleSheetValidation {
  21. static validateStyleProp(prop: string, style: Object, caller: string) {
  22. if (!__DEV__ || global.__RCTProfileIsProfiling) {
  23. return;
  24. }
  25. if (allStylePropTypes[prop] === undefined) {
  26. const message1 = '"' + prop + '" is not a valid style property.';
  27. const message2 =
  28. '\nValid style props: ' +
  29. JSON.stringify(Object.keys(allStylePropTypes).sort(), null, ' ');
  30. styleError(message1, style, caller, message2);
  31. }
  32. const error = allStylePropTypes[prop](
  33. style,
  34. prop,
  35. caller,
  36. 'prop',
  37. null,
  38. ReactPropTypesSecret,
  39. );
  40. if (error) {
  41. styleError(error.message, style, caller);
  42. }
  43. }
  44. static validateStyle(name: string, styles: Object) {
  45. if (!__DEV__ || global.__RCTProfileIsProfiling) {
  46. return;
  47. }
  48. if (!styles[name]) {
  49. return;
  50. }
  51. const styleProps = Object.keys(styles[name]);
  52. for (const prop of styleProps) {
  53. StyleSheetValidation.validateStyleProp(
  54. prop,
  55. styles[name],
  56. 'StyleSheet ' + name,
  57. );
  58. }
  59. }
  60. /* $FlowFixMe(>=0.85.0 site=react_native_fb) This comment suppresses an error
  61. * found when Flow v0.85 was deployed. To see the error, delete this comment
  62. * and run Flow. */
  63. static addValidStylePropTypes(stylePropTypes) {
  64. if (!__DEV__ || global.__RCTProfileIsProfiling) {
  65. return;
  66. }
  67. for (const key in stylePropTypes) {
  68. allStylePropTypes[key] = stylePropTypes[key];
  69. }
  70. }
  71. }
  72. const styleError = function(message1, style, caller?, message2?) {
  73. invariant(
  74. false,
  75. message1 +
  76. '\n' +
  77. (caller || '<<unknown>>') +
  78. ': ' +
  79. JSON.stringify(style, null, ' ') +
  80. (message2 || ''),
  81. );
  82. };
  83. const allStylePropTypes = {};
  84. if (__DEV__ && !global.__RCTProfileIsProfiling) {
  85. StyleSheetValidation.addValidStylePropTypes(DeprecatedImageStylePropTypes);
  86. StyleSheetValidation.addValidStylePropTypes(DeprecatedTextStylePropTypes);
  87. StyleSheetValidation.addValidStylePropTypes(DeprecatedViewStylePropTypes);
  88. }
  89. module.exports = StyleSheetValidation;