    /**
     * @file button.js
     */
    import Component from './component';
    import * as Dom from './utils/dom.js';
    import * as Events from './utils/events.js';
    import * as Fn from './utils/fn.js';
    import log from './utils/log.js';
    import document from 'global/document';
    import {assign} from './utils/obj';

    /**
     * Clickable Component which is clickable or keyboard actionable,
     * but is not a native HTML button.
     *
     * @extends Component
     */
    class ClickableComponent extends Component {

      /**
       * Creates an instance of this class.
       *
       * @param  {Player} player
       *         The `Player` that this class should be attached to.
       *
       * @param  {Object} [options]
       *         The key/value store of player options.
       */
      constructor(player, options) {
        super(player, options);

        this.emitTapEvents();

        this.enable();
      }

      /**
       * Create the `Component`s DOM element.
       *
       * @param {string} [tag=div]
       *        The element's node type.
       *
       * @param {Object} [props={}]
       *        An object of properties that should be set on the element.
       *
       * @param {Object} [attributes={}]
       *        An object of attributes that should be set on the element.
       *
       * @return {Element}
       *         The element that gets created.
       */
      createEl(tag = 'div', props = {}, attributes = {}) {
        props = assign({
          innerHTML: '<span aria-hidden="true" class="vjs-icon-placeholder"></span>',
          className: this.buildCSSClass(),
          tabIndex: 0
        }, props);

        if (tag === 'button') {
          log.error(`Creating a ClickableComponent with an HTML element of ${tag} is not supported; use a Button instead.`);
        }

        // Add ARIA attributes for clickable element which is not a native HTML button
        attributes = assign({
          'role': 'button',

          // let the screen reader user know that the text of the element may change
          'aria-live': 'polite'
        }, attributes);

        this.tabIndex_ = props.tabIndex;

        const el = super.createEl(tag, props, attributes);

        this.createControlTextEl(el);

        return el;
      }

      /**
       * Create a control text element on this `Component`
       *
       * @param {Element} [el]
       *        Parent element for the control text.
       *
       * @return {Element}
       *         The control text element that gets created.
       */
      createControlTextEl(el) {
        this.controlTextEl_ = Dom.createEl('span', {
          className: 'vjs-control-text'
        });

        if (el) {
          el.appendChild(this.controlTextEl_);
        }

        this.controlText(this.controlText_, el);

        return this.controlTextEl_;
      }

      /**
       * Get or set the localize text to use for the controls on the `Component`.
       *
       * @param {string} [text]
       *        Control text for element.
       *
       * @param {Element} [el=this.el()]
       *        Element to set the title on.
       *
       * @return {string}
       *         - The control text when getting
       */
      controlText(text, el = this.el()) {
        if (!text) {
          return this.controlText_ || 'Need Text';
        }

        const localizedText = this.localize(text);

        this.controlText_ = text;
        Dom.textContent(this.controlTextEl_, localizedText);
        if (!this.nonIconControl) {
          // Set title attribute if only an icon is shown
          el.setAttribute('title', localizedText);
        }
      }

      /**
       * Builds the default DOM `className`.
       *
       * @return {string}
       *         The DOM `className` for this object.
       */
      buildCSSClass() {
        return `vjs-control vjs-button ${super.buildCSSClass()}`;
      }

      /**
       * Enable this `Component`s element.
       */
      enable() {
        if (!this.enabled_) {
          this.enabled_ = true;
          this.removeClass('vjs-disabled');
          this.el_.setAttribute('aria-disabled', 'false');
          if (typeof this.tabIndex_ !== 'undefined') {
            this.el_.setAttribute('tabIndex', this.tabIndex_);
          }
          this.on(['tap', 'click'], this.handleClick);
          this.on('focus', this.handleFocus);
          this.on('blur', this.handleBlur);
        }
      }

      /**
       * Disable this `Component`s element.
       */
      disable() {
        this.enabled_ = false;
        this.addClass('vjs-disabled');
        this.el_.setAttribute('aria-disabled', 'true');
        if (typeof this.tabIndex_ !== 'undefined') {
          this.el_.removeAttribute('tabIndex');
        }
        this.off(['tap', 'click'], this.handleClick);
        this.off('focus', this.handleFocus);
        this.off('blur', this.handleBlur);
      }

      /**
       * This gets called when a `ClickableComponent` gets:
       * - Clicked (via the `click` event, listening starts in the constructor)
       * - Tapped (via the `tap` event, listening starts in the constructor)
       * - The following things happen in order:
       *   1. {@link ClickableComponent#handleFocus} is called via a `focus` event on the
       *      `ClickableComponent`.
       *   2. {@link ClickableComponent#handleFocus} adds a listener for `keydown` on using
       *      {@link ClickableComponent#handleKeyPress}.
       *   3. `ClickableComponent` has not had a `blur` event (`blur` means that focus was lost). The user presses
       *      the space or enter key.
       *   4. {@link ClickableComponent#handleKeyPress} calls this function with the `keydown`
       *      event as a parameter.
       *
       * @param {EventTarget~Event} event
       *        The `keydown`, `tap`, or `click` event that caused this function to be
       *        called.
       *
       * @listens tap
       * @listens click
       * @abstract
       */
      handleClick(event) {}

      /**
       * This gets called when a `ClickableComponent` gains focus via a `focus` event.
       * Turns on listening for `keydown` events. When they happen it
       * calls `this.handleKeyPress`.
       *
       * @param {EventTarget~Event} event
       *        The `focus` event that caused this function to be called.
       *
       * @listens focus
       */
      handleFocus(event) {
        Events.on(document, 'keydown', Fn.bind(this, this.handleKeyPress));
      }

      /**
       * Called when this ClickableComponent has focus and a key gets pressed down. By
       * default it will call `this.handleClick` when the key is space or enter.
       *
       * @param {EventTarget~Event} event
       *        The `keydown` event that caused this function to be called.
       *
       * @listens keydown
       */
      handleKeyPress(event) {

        // Support Space (32) or Enter (13) key operation to fire a click event
        if (event.which === 32 || event.which === 13) {
          event.preventDefault();
          this.trigger('click');
        } else if (super.handleKeyPress) {

          // Pass keypress handling up for unsupported keys
          super.handleKeyPress(event);
        }
      }

      /**
       * Called when a `ClickableComponent` loses focus. Turns off the listener for
       * `keydown` events. Which Stops `this.handleKeyPress` from getting called.
       *
       * @param {EventTarget~Event} event
       *        The `blur` event that caused this function to be called.
       *
       * @listens blur
       */
      handleBlur(event) {
        Events.off(document, 'keydown', Fn.bind(this, this.handleKeyPress));
      }
    }

    Component.registerComponent('ClickableComponent', ClickableComponent);
    export default ClickableComponent;