Source: lib/util/fake_event_target.js

  1. /**
  2. * @license
  3. * Copyright 2016 Google Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. goog.provide('shaka.util.FakeEventTarget');
  18. goog.require('goog.asserts');
  19. goog.require('shaka.log');
  20. goog.require('shaka.util.FakeEvent');
  21. goog.require('shaka.util.MultiMap');
  22. /**
  23. * A work-alike for EventTarget. Only DOM elements may be true EventTargets,
  24. * but this can be used as a base class to provide event dispatch to non-DOM
  25. * classes. Only FakeEvents should be dispatched.
  26. *
  27. * @struct
  28. * @constructor
  29. * @implements {EventTarget}
  30. * @exportInterface
  31. */
  32. shaka.util.FakeEventTarget = function() {
  33. /**
  34. * @private {!shaka.util.MultiMap.<shaka.util.FakeEventTarget.ListenerType>}
  35. */
  36. this.listeners_ = new shaka.util.MultiMap();
  37. /**
  38. * The target of all dispatched events. Defaults to |this|.
  39. * @type {EventTarget}
  40. */
  41. this.dispatchTarget = this;
  42. };
  43. /**
  44. * These are the listener types defined in the closure extern for EventTarget.
  45. * @typedef {EventListener|function(!Event):(boolean|undefined)}
  46. * @exportInterface
  47. */
  48. shaka.util.FakeEventTarget.ListenerType;
  49. /**
  50. * Add an event listener to this object.
  51. *
  52. * @param {string} type The event type to listen for.
  53. * @param {shaka.util.FakeEventTarget.ListenerType} listener The callback or
  54. * listener object to invoke.
  55. * @param {(!AddEventListenerOptions|boolean)=} opt_options Ignored.
  56. * @override
  57. * @exportInterface
  58. */
  59. shaka.util.FakeEventTarget.prototype.addEventListener =
  60. function(type, listener, opt_options) {
  61. this.listeners_.push(type, listener);
  62. };
  63. /**
  64. * Remove an event listener from this object.
  65. *
  66. * @param {string} type The event type for which you wish to remove a listener.
  67. * @param {shaka.util.FakeEventTarget.ListenerType} listener The callback or
  68. * listener object to remove.
  69. * @param {(EventListenerOptions|boolean)=} opt_options Ignored.
  70. * @override
  71. * @exportInterface
  72. */
  73. shaka.util.FakeEventTarget.prototype.removeEventListener =
  74. function(type, listener, opt_options) {
  75. this.listeners_.remove(type, listener);
  76. };
  77. /**
  78. * Dispatch an event from this object.
  79. *
  80. * @param {!Event} event The event to be dispatched from this object.
  81. * @return {boolean} True if the default action was prevented.
  82. * @override
  83. * @exportInterface
  84. */
  85. shaka.util.FakeEventTarget.prototype.dispatchEvent = function(event) {
  86. // In many browsers, it is complex to overwrite properties of actual Events.
  87. // Here we expect only to dispatch FakeEvents, which are simpler.
  88. goog.asserts.assert(event instanceof shaka.util.FakeEvent,
  89. 'FakeEventTarget can only dispatch FakeEvents!');
  90. var list = this.listeners_.get(event.type) || [];
  91. for (var i = 0; i < list.length; ++i) {
  92. // Do this every time, since events can be re-dispatched from handlers.
  93. event.target = this.dispatchTarget;
  94. event.currentTarget = this.dispatchTarget;
  95. var listener = list[i];
  96. try {
  97. if (listener.handleEvent) {
  98. listener.handleEvent(event);
  99. } else {
  100. listener.call(this, event);
  101. }
  102. } catch (exception) {
  103. // Exceptions during event handlers should not affect the caller,
  104. // but should appear on the console as uncaught, according to MDN:
  105. // http://goo.gl/N6Ff27
  106. shaka.log.error('Uncaught exception in event handler', exception);
  107. }
  108. if (event.stopped) {
  109. break;
  110. }
  111. }
  112. return event.defaultPrevented;
  113. };