You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

151 lines
4.4 KiB

  1. // @flow
  2. import format from './format';
  3. import { modifierPhases } from '../enums';
  4. const INVALID_MODIFIER_ERROR =
  5. 'Popper: modifier "%s" provided an invalid %s property, expected %s but got %s';
  6. const MISSING_DEPENDENCY_ERROR =
  7. 'Popper: modifier "%s" requires "%s", but "%s" modifier is not available';
  8. const VALID_PROPERTIES = [
  9. 'name',
  10. 'enabled',
  11. 'phase',
  12. 'fn',
  13. 'effect',
  14. 'requires',
  15. 'options',
  16. ];
  17. export default function validateModifiers(modifiers: Array<any>): void {
  18. modifiers.forEach((modifier) => {
  19. [...Object.keys(modifier), ...VALID_PROPERTIES]
  20. // IE11-compatible replacement for `new Set(iterable)`
  21. .filter((value, index, self) => self.indexOf(value) === index)
  22. .forEach((key) => {
  23. switch (key) {
  24. case 'name':
  25. if (typeof modifier.name !== 'string') {
  26. console.error(
  27. format(
  28. INVALID_MODIFIER_ERROR,
  29. String(modifier.name),
  30. '"name"',
  31. '"string"',
  32. `"${String(modifier.name)}"`
  33. )
  34. );
  35. }
  36. break;
  37. case 'enabled':
  38. if (typeof modifier.enabled !== 'boolean') {
  39. console.error(
  40. format(
  41. INVALID_MODIFIER_ERROR,
  42. modifier.name,
  43. '"enabled"',
  44. '"boolean"',
  45. `"${String(modifier.enabled)}"`
  46. )
  47. );
  48. }
  49. break;
  50. case 'phase':
  51. if (modifierPhases.indexOf(modifier.phase) < 0) {
  52. console.error(
  53. format(
  54. INVALID_MODIFIER_ERROR,
  55. modifier.name,
  56. '"phase"',
  57. `either ${modifierPhases.join(', ')}`,
  58. `"${String(modifier.phase)}"`
  59. )
  60. );
  61. }
  62. break;
  63. case 'fn':
  64. if (typeof modifier.fn !== 'function') {
  65. console.error(
  66. format(
  67. INVALID_MODIFIER_ERROR,
  68. modifier.name,
  69. '"fn"',
  70. '"function"',
  71. `"${String(modifier.fn)}"`
  72. )
  73. );
  74. }
  75. break;
  76. case 'effect':
  77. if (
  78. modifier.effect != null &&
  79. typeof modifier.effect !== 'function'
  80. ) {
  81. console.error(
  82. format(
  83. INVALID_MODIFIER_ERROR,
  84. modifier.name,
  85. '"effect"',
  86. '"function"',
  87. `"${String(modifier.fn)}"`
  88. )
  89. );
  90. }
  91. break;
  92. case 'requires':
  93. if (
  94. modifier.requires != null &&
  95. !Array.isArray(modifier.requires)
  96. ) {
  97. console.error(
  98. format(
  99. INVALID_MODIFIER_ERROR,
  100. modifier.name,
  101. '"requires"',
  102. '"array"',
  103. `"${String(modifier.requires)}"`
  104. )
  105. );
  106. }
  107. break;
  108. case 'requiresIfExists':
  109. if (!Array.isArray(modifier.requiresIfExists)) {
  110. console.error(
  111. format(
  112. INVALID_MODIFIER_ERROR,
  113. modifier.name,
  114. '"requiresIfExists"',
  115. '"array"',
  116. `"${String(modifier.requiresIfExists)}"`
  117. )
  118. );
  119. }
  120. break;
  121. case 'options':
  122. case 'data':
  123. break;
  124. default:
  125. console.error(
  126. `PopperJS: an invalid property has been provided to the "${
  127. modifier.name
  128. }" modifier, valid properties are ${VALID_PROPERTIES.map(
  129. (s) => `"${s}"`
  130. ).join(', ')}; but "${key}" was provided.`
  131. );
  132. }
  133. modifier.requires &&
  134. modifier.requires.forEach((requirement) => {
  135. if (modifiers.find((mod) => mod.name === requirement) == null) {
  136. console.error(
  137. format(
  138. MISSING_DEPENDENCY_ERROR,
  139. String(modifier.name),
  140. requirement,
  141. requirement
  142. )
  143. );
  144. }
  145. });
  146. });
  147. });
  148. }