1. 1 : /**
  2. 2 : * @file volume-control.js
  3. 3 : */
  4. 4 : import Component from '../../component.js';
  5. 5 : import checkVolumeSupport from './check-volume-support';
  6. 6 : import {isPlain} from '../../utils/obj';
  7. 7 : import {throttle, bind, UPDATE_REFRESH_INTERVAL} from '../../utils/fn.js';
  8. 8 :
  9. 9 : // Required children
  10. 10 : import './volume-bar.js';
  11. 11 :
  12. 12 : /**
  13. 13 : * The component for controlling the volume level
  14. 14 : *
  15. 15 : * @extends Component
  16. 16 : */
  17. 17 : class VolumeControl extends Component {
  18. 18 :
  19. 19 : /**
  20. 20 : * Creates an instance of this class.
  21. 21 : *
  22. 22 : * @param {Player} player
  23. 23 : * The `Player` that this class should be attached to.
  24. 24 : *
  25. 25 : * @param {Object} [options={}]
  26. 26 : * The key/value store of player options.
  27. 27 : */
  28. 28 : constructor(player, options = {}) {
  29. 29 : options.vertical = options.vertical || false;
  30. 30 :
  31. 31 : // Pass the vertical option down to the VolumeBar if
  32. 32 : // the VolumeBar is turned on.
  33. 33 : if (typeof options.volumeBar === 'undefined' || isPlain(options.volumeBar)) {
  34. 34 : options.volumeBar = options.volumeBar || {};
  35. 35 : options.volumeBar.vertical = options.vertical;
  36. 36 : }
  37. 37 :
  38. 38 : super(player, options);
  39. 39 :
  40. 40 : // hide this control if volume support is missing
  41. 41 : checkVolumeSupport(this, player);
  42. 42 :
  43. 43 : this.throttledHandleMouseMove = throttle(bind(this, this.handleMouseMove), UPDATE_REFRESH_INTERVAL);
  44. 44 : this.handleMouseUpHandler_ = (e) => this.handleMouseUp(e);
  45. 45 :
  46. 46 : this.on('mousedown', (e) => this.handleMouseDown(e));
  47. 47 : this.on('touchstart', (e) => this.handleMouseDown(e));
  48. 48 : this.on('mousemove', (e) => this.handleMouseMove(e));
  49. 49 :
  50. 50 : // while the slider is active (the mouse has been pressed down and
  51. 51 : // is dragging) or in focus we do not want to hide the VolumeBar
  52. 52 : this.on(this.volumeBar, ['focus', 'slideractive'], () => {
  53. 53 : this.volumeBar.addClass('vjs-slider-active');
  54. 54 : this.addClass('vjs-slider-active');
  55. 55 : this.trigger('slideractive');
  56. 56 : });
  57. 57 :
  58. 58 : this.on(this.volumeBar, ['blur', 'sliderinactive'], () => {
  59. 59 : this.volumeBar.removeClass('vjs-slider-active');
  60. 60 : this.removeClass('vjs-slider-active');
  61. 61 : this.trigger('sliderinactive');
  62. 62 : });
  63. 63 : }
  64. 64 :
  65. 65 : /**
  66. 66 : * Create the `Component`'s DOM element
  67. 67 : *
  68. 68 : * @return {Element}
  69. 69 : * The element that was created.
  70. 70 : */
  71. 71 : createEl() {
  72. 72 : let orientationClass = 'vjs-volume-horizontal';
  73. 73 :
  74. 74 : if (this.options_.vertical) {
  75. 75 : orientationClass = 'vjs-volume-vertical';
  76. 76 : }
  77. 77 :
  78. 78 : return super.createEl('div', {
  79. 79 : className: `vjs-volume-control vjs-control ${orientationClass}`
  80. 80 : });
  81. 81 : }
  82. 82 :
  83. 83 : /**
  84. 84 : * Handle `mousedown` or `touchstart` events on the `VolumeControl`.
  85. 85 : *
  86. 86 : * @param {EventTarget~Event} event
  87. 87 : * `mousedown` or `touchstart` event that triggered this function
  88. 88 : *
  89. 89 : * @listens mousedown
  90. 90 : * @listens touchstart
  91. 91 : */
  92. 92 : handleMouseDown(event) {
  93. 93 : const doc = this.el_.ownerDocument;
  94. 94 :
  95. 95 : this.on(doc, 'mousemove', this.throttledHandleMouseMove);
  96. 96 : this.on(doc, 'touchmove', this.throttledHandleMouseMove);
  97. 97 : this.on(doc, 'mouseup', this.handleMouseUpHandler_);
  98. 98 : this.on(doc, 'touchend', this.handleMouseUpHandler_);
  99. 99 : }
  100. 100 :
  101. 101 : /**
  102. 102 : * Handle `mouseup` or `touchend` events on the `VolumeControl`.
  103. 103 : *
  104. 104 : * @param {EventTarget~Event} event
  105. 105 : * `mouseup` or `touchend` event that triggered this function.
  106. 106 : *
  107. 107 : * @listens touchend
  108. 108 : * @listens mouseup
  109. 109 : */
  110. 110 : handleMouseUp(event) {
  111. 111 : const doc = this.el_.ownerDocument;
  112. 112 :
  113. 113 : this.off(doc, 'mousemove', this.throttledHandleMouseMove);
  114. 114 : this.off(doc, 'touchmove', this.throttledHandleMouseMove);
  115. 115 : this.off(doc, 'mouseup', this.handleMouseUpHandler_);
  116. 116 : this.off(doc, 'touchend', this.handleMouseUpHandler_);
  117. 117 : }
  118. 118 :
  119. 119 : /**
  120. 120 : * Handle `mousedown` or `touchstart` events on the `VolumeControl`.
  121. 121 : *
  122. 122 : * @param {EventTarget~Event} event
  123. 123 : * `mousedown` or `touchstart` event that triggered this function
  124. 124 : *
  125. 125 : * @listens mousedown
  126. 126 : * @listens touchstart
  127. 127 : */
  128. 128 : handleMouseMove(event) {
  129. 129 : this.volumeBar.handleMouseMove(event);
  130. 130 : }
  131. 131 : }
  132. 132 :
  133. 133 : /**
  134. 134 : * Default options for the `VolumeControl`
  135. 135 : *
  136. 136 : * @type {Object}
  137. 137 : * @private
  138. 138 : */
  139. 139 : VolumeControl.prototype.options_ = {
  140. 140 : children: [
  141. 141 : 'volumeBar'
  142. 142 : ]
  143. 143 : };
  144. 144 :
  145. 145 : Component.registerComponent('VolumeControl', VolumeControl);
  146. 146 : export default VolumeControl;