Source: lib/util/fake_event.js

  1. /*! @license
  2. * Shaka Player
  3. * Copyright 2016 Google LLC
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. goog.provide('shaka.util.FakeEvent');
  7. goog.require('goog.asserts');
  8. /**
  9. * @summary Create an Event work-alike object based on the provided dictionary.
  10. * The event should contain all of the same properties from the dict.
  11. *
  12. * @extends {Event}
  13. * @export
  14. */
  15. shaka.util.FakeEvent = class {
  16. /**
  17. * @param {!Event} event
  18. * @return {!shaka.util.FakeEvent}
  19. */
  20. static fromRealEvent(event) {
  21. const fakeEvent = new shaka.util.FakeEvent(event.type);
  22. for (const key in event) {
  23. Object.defineProperty(fakeEvent, key, {
  24. value: event[key],
  25. writable: true,
  26. enumerable: true,
  27. });
  28. }
  29. return fakeEvent;
  30. }
  31. /**
  32. * Allows us to tell the compiler that the dictionary "map" is actually a
  33. * generic object, for backwards compatibility.
  34. * @param {!Map.<string, Object>} dict
  35. * @return {!Object}
  36. * @suppress {invalidCasts}
  37. * @private
  38. */
  39. static recastDictAsObject_(dict) {
  40. goog.asserts.assert(!(dict instanceof Map), 'dict should not be a map');
  41. return /** @type {!Object} */ (dict);
  42. }
  43. /**
  44. * @param {string} type
  45. * @param {Map.<string, Object>=} dict
  46. */
  47. constructor(type, dict) {
  48. if (dict) {
  49. if (dict instanceof Map) {
  50. // Take properties from dict if present.
  51. for (const key of dict.keys()) {
  52. Object.defineProperty(this, key, {
  53. value: dict.get(key),
  54. writable: true,
  55. enumerable: true,
  56. });
  57. }
  58. } else {
  59. // For backwards compatibility with external apps that may make use of
  60. // this public constructor, this should still accept generic objects.
  61. const obj = shaka.util.FakeEvent.recastDictAsObject_(dict);
  62. for (const key in obj) {
  63. Object.defineProperty(this, key, {
  64. value: obj[key],
  65. writable: true,
  66. enumerable: true,
  67. });
  68. }
  69. }
  70. }
  71. // The properties below cannot be set by the dict. They are all provided
  72. // for compatibility with native events.
  73. /** @const {boolean} */
  74. this.bubbles = false;
  75. /** @type {boolean} */
  76. this.cancelable = false;
  77. /** @type {boolean} */
  78. this.defaultPrevented = false;
  79. /**
  80. * According to MDN, Chrome uses high-res timers instead of epoch time.
  81. * Follow suit so that timeStamps on FakeEvents use the same base as
  82. * on native Events.
  83. * @const {number}
  84. * @see https://developer.mozilla.org/en-US/docs/Web/API/Event/timeStamp
  85. */
  86. this.timeStamp = window.performance && window.performance.now ?
  87. window.performance.now() : Date.now();
  88. /** @const {string} */
  89. this.type = type;
  90. /** @const {boolean} */
  91. this.isTrusted = false;
  92. /** @type {EventTarget} */
  93. this.currentTarget = null;
  94. /** @type {EventTarget} */
  95. this.target = null;
  96. /**
  97. * Non-standard property read by FakeEventTarget to stop processing
  98. * listeners.
  99. * @type {boolean}
  100. */
  101. this.stopped = false;
  102. }
  103. /**
  104. * Prevents the default action of the event. Has no effect if the event isn't
  105. * cancellable.
  106. * @override
  107. */
  108. preventDefault() {
  109. if (this.cancelable) {
  110. this.defaultPrevented = true;
  111. }
  112. }
  113. /**
  114. * Stops processing event listeners for this event. Provided for
  115. * compatibility with native Events.
  116. * @override
  117. */
  118. stopImmediatePropagation() {
  119. this.stopped = true;
  120. }
  121. /**
  122. * Does nothing, since FakeEvents do not bubble. Provided for compatibility
  123. * with native Events.
  124. * @override
  125. */
  126. stopPropagation() {}
  127. };
  128. /**
  129. * An internal enum that contains the string values of all of the player events.
  130. * This exists primarily to act as an implicit list of events, for tests.
  131. *
  132. * @enum {string}
  133. */
  134. shaka.util.FakeEvent.EventName = {
  135. AbrStatusChanged: 'abrstatuschanged',
  136. Adaptation: 'adaptation',
  137. Buffering: 'buffering',
  138. Complete: 'complete',
  139. DownloadFailed: 'downloadfailed',
  140. DownloadHeadersReceived: 'downloadheadersreceived',
  141. DrmSessionUpdate: 'drmsessionupdate',
  142. Emsg: 'emsg',
  143. Prft: 'prft',
  144. Error: 'error',
  145. ExpirationUpdated: 'expirationupdated',
  146. FirstQuartile: 'firstquartile',
  147. GapJumped: 'gapjumped',
  148. KeyStatusChanged: 'keystatuschanged',
  149. Loaded: 'loaded',
  150. Loading: 'loading',
  151. ManifestParsed: 'manifestparsed',
  152. ManifestUpdated: 'manifestupdated',
  153. MediaQualityChanged: 'mediaqualitychanged',
  154. Metadata: 'metadata',
  155. Midpoint: 'midpoint',
  156. NoSpatialVideoInfoEvent: 'nospatialvideoinfo',
  157. OnStateChange: 'onstatechange',
  158. RateChange: 'ratechange',
  159. SegmentAppended: 'segmentappended',
  160. SessionDataEvent: 'sessiondata',
  161. SpatialVideoInfoEvent: 'spatialvideoinfo',
  162. StallDetected: 'stalldetected',
  163. Started: 'started',
  164. StateChanged: 'statechanged',
  165. Streaming: 'streaming',
  166. TextChanged: 'textchanged',
  167. TextTrackVisibility: 'texttrackvisibility',
  168. ThirdQuartile: 'thirdquartile',
  169. TimelineRegionAdded: 'timelineregionadded',
  170. TimelineRegionEnter: 'timelineregionenter',
  171. TimelineRegionExit: 'timelineregionexit',
  172. TracksChanged: 'trackschanged',
  173. Unloading: 'unloading',
  174. VariantChanged: 'variantchanged',
  175. };