util.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. import $ from 'jquery'
  2. /**
  3. * --------------------------------------------------------------------------
  4. * Bootstrap (v4.1.3): util.js
  5. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  6. * --------------------------------------------------------------------------
  7. */
  8. const Util = (($) => {
  9. /**
  10. * ------------------------------------------------------------------------
  11. * Private TransitionEnd Helpers
  12. * ------------------------------------------------------------------------
  13. */
  14. const TRANSITION_END = 'transitionend'
  15. const MAX_UID = 1000000
  16. const MILLISECONDS_MULTIPLIER = 1000
  17. // Shoutout AngusCroll (https://goo.gl/pxwQGp)
  18. function toType(obj) {
  19. return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase()
  20. }
  21. function getSpecialTransitionEndEvent() {
  22. return {
  23. bindType: TRANSITION_END,
  24. delegateType: TRANSITION_END,
  25. handle(event) {
  26. if ($(event.target).is(this)) {
  27. return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params
  28. }
  29. return undefined // eslint-disable-line no-undefined
  30. }
  31. }
  32. }
  33. function transitionEndEmulator(duration) {
  34. let called = false
  35. $(this).one(Util.TRANSITION_END, () => {
  36. called = true
  37. })
  38. setTimeout(() => {
  39. if (!called) {
  40. Util.triggerTransitionEnd(this)
  41. }
  42. }, duration)
  43. return this
  44. }
  45. function setTransitionEndSupport() {
  46. $.fn.emulateTransitionEnd = transitionEndEmulator
  47. $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent()
  48. }
  49. /**
  50. * --------------------------------------------------------------------------
  51. * Public Util Api
  52. * --------------------------------------------------------------------------
  53. */
  54. const Util = {
  55. TRANSITION_END: 'bsTransitionEnd',
  56. getUID(prefix) {
  57. do {
  58. // eslint-disable-next-line no-bitwise
  59. prefix += ~~(Math.random() * MAX_UID) // "~~" acts like a faster Math.floor() here
  60. } while (document.getElementById(prefix))
  61. return prefix
  62. },
  63. getSelectorFromElement(element) {
  64. let selector = element.getAttribute('data-target')
  65. if (!selector || selector === '#') {
  66. selector = element.getAttribute('href') || ''
  67. }
  68. try {
  69. return document.querySelector(selector) ? selector : null
  70. } catch (err) {
  71. return null
  72. }
  73. },
  74. getTransitionDurationFromElement(element) {
  75. if (!element) {
  76. return 0
  77. }
  78. // Get transition-duration of the element
  79. let transitionDuration = $(element).css('transition-duration')
  80. const floatTransitionDuration = parseFloat(transitionDuration)
  81. // Return 0 if element or transition duration is not found
  82. if (!floatTransitionDuration) {
  83. return 0
  84. }
  85. // If multiple durations are defined, take the first
  86. transitionDuration = transitionDuration.split(',')[0]
  87. return parseFloat(transitionDuration) * MILLISECONDS_MULTIPLIER
  88. },
  89. reflow(element) {
  90. return element.offsetHeight
  91. },
  92. triggerTransitionEnd(element) {
  93. $(element).trigger(TRANSITION_END)
  94. },
  95. // TODO: Remove in v5
  96. supportsTransitionEnd() {
  97. return Boolean(TRANSITION_END)
  98. },
  99. isElement(obj) {
  100. return (obj[0] || obj).nodeType
  101. },
  102. typeCheckConfig(componentName, config, configTypes) {
  103. for (const property in configTypes) {
  104. if (Object.prototype.hasOwnProperty.call(configTypes, property)) {
  105. const expectedTypes = configTypes[property]
  106. const value = config[property]
  107. const valueType = value && Util.isElement(value)
  108. ? 'element' : toType(value)
  109. if (!new RegExp(expectedTypes).test(valueType)) {
  110. throw new Error(
  111. `${componentName.toUpperCase()}: ` +
  112. `Option "${property}" provided type "${valueType}" ` +
  113. `but expected type "${expectedTypes}".`)
  114. }
  115. }
  116. }
  117. }
  118. }
  119. setTransitionEndSupport()
  120. return Util
  121. })($)
  122. export default Util