1. 1 : /**
  2. 2 : * @file button.js
  3. 3 : */
  4. 4 : import ClickableComponent from './clickable-component.js';
  5. 5 : import Component from './component';
  6. 6 : import log from './utils/log.js';
  7. 7 : import {assign} from './utils/obj';
  8. 8 : import keycode from 'keycode';
  9. 9 : import {createEl} from './utils/dom.js';
  10. 10 :
  11. 11 : /**
  12. 12 : * Base class for all buttons.
  13. 13 : *
  14. 14 : * @extends ClickableComponent
  15. 15 : */
  16. 16 : class Button extends ClickableComponent {
  17. 17 :
  18. 18 : /**
  19. 19 : * Create the `Button`s DOM element.
  20. 20 : *
  21. 21 : * @param {string} [tag="button"]
  22. 22 : * The element's node type. This argument is IGNORED: no matter what
  23. 23 : * is passed, it will always create a `button` element.
  24. 24 : *
  25. 25 : * @param {Object} [props={}]
  26. 26 : * An object of properties that should be set on the element.
  27. 27 : *
  28. 28 : * @param {Object} [attributes={}]
  29. 29 : * An object of attributes that should be set on the element.
  30. 30 : *
  31. 31 : * @return {Element}
  32. 32 : * The element that gets created.
  33. 33 : */
  34. 34 : createEl(tag, props = {}, attributes = {}) {
  35. 35 : tag = 'button';
  36. 36 :
  37. 37 : props = assign({
  38. 38 : className: this.buildCSSClass()
  39. 39 : }, props);
  40. 40 :
  41. 41 : // Add attributes for button element
  42. 42 : attributes = assign({
  43. 43 :
  44. 44 : // Necessary since the default button type is "submit"
  45. 45 : type: 'button'
  46. 46 : }, attributes);
  47. 47 :
  48. 48 : const el = createEl(tag, props, attributes);
  49. 49 :
  50. 50 : el.appendChild(createEl('span', {
  51. 51 : className: 'vjs-icon-placeholder'
  52. 52 : }, {
  53. 53 : 'aria-hidden': true
  54. 54 : }));
  55. 55 :
  56. 56 : this.createControlTextEl(el);
  57. 57 :
  58. 58 : return el;
  59. 59 : }
  60. 60 :
  61. 61 : /**
  62. 62 : * Add a child `Component` inside of this `Button`.
  63. 63 : *
  64. 64 : * @param {string|Component} child
  65. 65 : * The name or instance of a child to add.
  66. 66 : *
  67. 67 : * @param {Object} [options={}]
  68. 68 : * The key/value store of options that will get passed to children of
  69. 69 : * the child.
  70. 70 : *
  71. 71 : * @return {Component}
  72. 72 : * The `Component` that gets added as a child. When using a string the
  73. 73 : * `Component` will get created by this process.
  74. 74 : *
  75. 75 : * @deprecated since version 5
  76. 76 : */
  77. 77 : addChild(child, options = {}) {
  78. 78 : const className = this.constructor.name;
  79. 79 :
  80. 80 : log.warn(`Adding an actionable (user controllable) child to a Button (${className}) is not supported; use a ClickableComponent instead.`);
  81. 81 :
  82. 82 : // Avoid the error message generated by ClickableComponent's addChild method
  83. 83 : return Component.prototype.addChild.call(this, child, options);
  84. 84 : }
  85. 85 :
  86. 86 : /**
  87. 87 : * Enable the `Button` element so that it can be activated or clicked. Use this with
  88. 88 : * {@link Button#disable}.
  89. 89 : */
  90. 90 : enable() {
  91. 91 : super.enable();
  92. 92 : this.el_.removeAttribute('disabled');
  93. 93 : }
  94. 94 :
  95. 95 : /**
  96. 96 : * Disable the `Button` element so that it cannot be activated or clicked. Use this with
  97. 97 : * {@link Button#enable}.
  98. 98 : */
  99. 99 : disable() {
  100. 100 : super.disable();
  101. 101 : this.el_.setAttribute('disabled', 'disabled');
  102. 102 : }
  103. 103 :
  104. 104 : /**
  105. 105 : * This gets called when a `Button` has focus and `keydown` is triggered via a key
  106. 106 : * press.
  107. 107 : *
  108. 108 : * @param {EventTarget~Event} event
  109. 109 : * The event that caused this function to get called.
  110. 110 : *
  111. 111 : * @listens keydown
  112. 112 : */
  113. 113 : handleKeyDown(event) {
  114. 114 :
  115. 115 : // Ignore Space or Enter key operation, which is handled by the browser for
  116. 116 : // a button - though not for its super class, ClickableComponent. Also,
  117. 117 : // prevent the event from propagating through the DOM and triggering Player
  118. 118 : // hotkeys. We do not preventDefault here because we _want_ the browser to
  119. 119 : // handle it.
  120. 120 : if (keycode.isEventKey(event, 'Space') || keycode.isEventKey(event, 'Enter')) {
  121. 121 : event.stopPropagation();
  122. 122 : return;
  123. 123 : }
  124. 124 :
  125. 125 : // Pass keypress handling up for unsupported keys
  126. 126 : super.handleKeyDown(event);
  127. 127 : }
  128. 128 : }
  129. 129 :
  130. 130 : Component.registerComponent('Button', Button);
  131. 131 : export default Button;