diff --git a/lib/ads/client_side_ad_manager.js b/lib/ads/client_side_ad_manager.js index 36deb84017..c12742b871 100644 --- a/lib/ads/client_side_ad_manager.js +++ b/lib/ads/client_side_ad_manager.js @@ -138,7 +138,7 @@ shaka.ads.ClientSideAdManager = class { // Remove ad breaks from the timeline this.onEvent_( new shaka.util.FakeEvent(shaka.ads.AdManager.CUEPOINTS_CHANGED, - {'cuepoints': []})); + (new Map()).set('cuepoints', []))); } @@ -151,17 +151,14 @@ shaka.ads.ClientSideAdManager = class { const now = Date.now() / 1000; const loadTime = now - this.requestAdsStartTime_; - this.onEvent_( - new shaka.util.FakeEvent(shaka.ads.AdManager.ADS_LOADED, - {'loadTime': loadTime})); + this.onEvent_(new shaka.util.FakeEvent(shaka.ads.AdManager.ADS_LOADED, + (new Map()).set('loadTime', loadTime))); this.imaAdsManager_ = e.getAdsManager(this.video_); this.onEvent_(new shaka.util.FakeEvent( shaka.ads.AdManager.IMA_AD_MANAGER_LOADED, - { - 'imaAdManager': this.imaAdsManager_, - })); + (new Map()).set('imaAdManager', this.imaAdsManager_))); const cuePointStarts = this.imaAdsManager_.getCuePoints(); if (cuePointStarts.length) { @@ -176,9 +173,9 @@ shaka.ads.ClientSideAdManager = class { cuePoints.push(shakaCuePoint); } - this.onEvent_( - new shaka.util.FakeEvent(shaka.ads.AdManager.CUEPOINTS_CHANGED, - {'cuepoints': cuePoints})); + this.onEvent_(new shaka.util.FakeEvent( + shaka.ads.AdManager.CUEPOINTS_CHANGED, + (new Map()).set('cuepoints', cuePoints))); } this.addImaEventListeners_(); @@ -228,6 +225,15 @@ shaka.ads.ClientSideAdManager = class { * @private */ addImaEventListeners_() { + /** + * @param {!Event} e + * @param {string} type + */ + const convertEventAndSend = (e, type) => { + const data = (new Map()).set('originalEvent', e); + this.onEvent_(new shaka.util.FakeEvent(type, data)); + }; + this.eventManager_.listen(this.imaAdsManager_, google.ima.AdErrorEvent.Type.AD_ERROR, (error) => { this.onAdError_(/** @type {!google.ima.AdErrorEvent} */ (error)); @@ -245,30 +251,22 @@ shaka.ads.ClientSideAdManager = class { this.eventManager_.listen(this.imaAdsManager_, google.ima.AdEvent.Type.FIRST_QUARTILE, (e) => { - this.onEvent_( - new shaka.util.FakeEvent(shaka.ads.AdManager.AD_FIRST_QUARTILE, - {'originalEvent': e})); + convertEventAndSend(e, shaka.ads.AdManager.AD_FIRST_QUARTILE); }); this.eventManager_.listen(this.imaAdsManager_, google.ima.AdEvent.Type.MIDPOINT, (e) => { - this.onEvent_( - new shaka.util.FakeEvent(shaka.ads.AdManager.AD_MIDPOINT, - {'originalEvent': e})); + convertEventAndSend(e, shaka.ads.AdManager.AD_MIDPOINT); }); this.eventManager_.listen(this.imaAdsManager_, google.ima.AdEvent.Type.THIRD_QUARTILE, (e) => { - this.onEvent_( - new shaka.util.FakeEvent(shaka.ads.AdManager.AD_THIRD_QUARTILE, - {'originalEvent': e})); + convertEventAndSend(e, shaka.ads.AdManager.AD_THIRD_QUARTILE); }); this.eventManager_.listen(this.imaAdsManager_, google.ima.AdEvent.Type.COMPLETE, (e) => { - this.onEvent_( - new shaka.util.FakeEvent(shaka.ads.AdManager.AD_COMPLETE, - {'originalEvent': e})); + convertEventAndSend(e, shaka.ads.AdManager.AD_COMPLETE); }); this.eventManager_.listen(this.imaAdsManager_, @@ -283,140 +281,102 @@ shaka.ads.ClientSideAdManager = class { this.eventManager_.listen(this.imaAdsManager_, google.ima.AdEvent.Type.SKIPPED, (e) => { - this.onEvent_( - new shaka.util.FakeEvent(shaka.ads.AdManager.AD_SKIPPED, - {'originalEvent': e})); + convertEventAndSend(e, shaka.ads.AdManager.AD_SKIPPED); }); this.eventManager_.listen(this.imaAdsManager_, google.ima.AdEvent.Type.VOLUME_CHANGED, (e) => { - this.onEvent_( - new shaka.util.FakeEvent(shaka.ads.AdManager.AD_VOLUME_CHANGED, - {'originalEvent': e})); + convertEventAndSend(e, shaka.ads.AdManager.AD_VOLUME_CHANGED); }); this.eventManager_.listen(this.imaAdsManager_, google.ima.AdEvent.Type.VOLUME_MUTED, (e) => { - this.onEvent_( - new shaka.util.FakeEvent(shaka.ads.AdManager.AD_MUTED, - {'originalEvent': e})); + convertEventAndSend(e, shaka.ads.AdManager.AD_MUTED); }); this.eventManager_.listen(this.imaAdsManager_, google.ima.AdEvent.Type.PAUSED, (e) => { goog.asserts.assert(this.ad_ != null, 'Ad should not be null!'); this.ad_.setPaused(true); - this.onEvent_( - new shaka.util.FakeEvent(shaka.ads.AdManager.AD_PAUSED, - {'originalEvent': e})); + convertEventAndSend(e, shaka.ads.AdManager.AD_PAUSED); }); this.eventManager_.listen(this.imaAdsManager_, google.ima.AdEvent.Type.RESUMED, (e) => { goog.asserts.assert(this.ad_ != null, 'Ad should not be null!'); this.ad_.setPaused(false); - this.onEvent_( - new shaka.util.FakeEvent(shaka.ads.AdManager.AD_RESUMED, - {'originalEvent': e})); + convertEventAndSend(e, shaka.ads.AdManager.AD_RESUMED); }); this.eventManager_.listen(this.imaAdsManager_, google.ima.AdEvent.Type.SKIPPABLE_STATE_CHANGED, (e) => { goog.asserts.assert(this.ad_ != null, 'Ad should not be null!'); - this.onEvent_(new shaka.util.FakeEvent( - shaka.ads.AdManager.AD_SKIP_STATE_CHANGED, - {'originalEvent': e})); + convertEventAndSend(e, shaka.ads.AdManager.AD_SKIP_STATE_CHANGED); }); this.eventManager_.listen(this.imaAdsManager_, google.ima.AdEvent.Type.CLICK, (e) => { - this.onEvent_(new shaka.util.FakeEvent( - shaka.ads.AdManager.AD_CLICKED, - {'originalEvent': e})); + convertEventAndSend(e, shaka.ads.AdManager.AD_CLICKED); }); this.eventManager_.listen(this.imaAdsManager_, google.ima.AdEvent.Type.AD_PROGRESS, (e) => { - this.onEvent_(new shaka.util.FakeEvent( - shaka.ads.AdManager.AD_PROGRESS, - {'originalEvent': e})); + convertEventAndSend(e, shaka.ads.AdManager.AD_PROGRESS); }); this.eventManager_.listen(this.imaAdsManager_, google.ima.AdEvent.Type.AD_BUFFERING, (e) => { - this.onEvent_(new shaka.util.FakeEvent( - shaka.ads.AdManager.AD_BUFFERING, - {'originalEvent': e})); + convertEventAndSend(e, shaka.ads.AdManager.AD_BUFFERING); }); this.eventManager_.listen(this.imaAdsManager_, google.ima.AdEvent.Type.IMPRESSION, (e) => { - this.onEvent_(new shaka.util.FakeEvent( - shaka.ads.AdManager.AD_IMPRESSION, - {'originalEvent': e})); + convertEventAndSend(e, shaka.ads.AdManager.AD_IMPRESSION); }); this.eventManager_.listen(this.imaAdsManager_, google.ima.AdEvent.Type.DURATION_CHANGE, (e) => { - this.onEvent_(new shaka.util.FakeEvent( - shaka.ads.AdManager.AD_DURATION_CHANGED, - {'originalEvent': e})); + convertEventAndSend(e, shaka.ads.AdManager.AD_DURATION_CHANGED); }); this.eventManager_.listen(this.imaAdsManager_, google.ima.AdEvent.Type.USER_CLOSE, (e) => { - this.onEvent_(new shaka.util.FakeEvent( - shaka.ads.AdManager.AD_CLOSED, - {'originalEvent': e})); + convertEventAndSend(e, shaka.ads.AdManager.AD_CLOSED); }); this.eventManager_.listen(this.imaAdsManager_, google.ima.AdEvent.Type.LOADED, (e) => { - this.onEvent_(new shaka.util.FakeEvent( - shaka.ads.AdManager.AD_LOADED, - {'originalEvent': e})); + convertEventAndSend(e, shaka.ads.AdManager.AD_LOADED); }); this.eventManager_.listen(this.imaAdsManager_, google.ima.AdEvent.Type.ALL_ADS_COMPLETED, (e) => { - this.onEvent_(new shaka.util.FakeEvent( - shaka.ads.AdManager.ALL_ADS_COMPLETED, - {'originalEvent': e})); + convertEventAndSend(e, shaka.ads.AdManager.ALL_ADS_COMPLETED); }); this.eventManager_.listen(this.imaAdsManager_, google.ima.AdEvent.Type.LINEAR_CHANGED, (e) => { - this.onEvent_(new shaka.util.FakeEvent( - shaka.ads.AdManager.AD_LINEAR_CHANGED, - {'originalEvent': e})); + convertEventAndSend(e, shaka.ads.AdManager.AD_LINEAR_CHANGED); }); this.eventManager_.listen(this.imaAdsManager_, google.ima.AdEvent.Type.AD_METADATA, (e) => { - this.onEvent_(new shaka.util.FakeEvent( - shaka.ads.AdManager.AD_METADATA, - {'originalEvent': e})); + convertEventAndSend(e, shaka.ads.AdManager.AD_METADATA); }); this.eventManager_.listen(this.imaAdsManager_, google.ima.AdEvent.Type.LOG, (e) => { - this.onEvent_(new shaka.util.FakeEvent( - shaka.ads.AdManager.AD_RECOVERABLE_ERROR, - {'originalEvent': e})); + convertEventAndSend(e, shaka.ads.AdManager.AD_RECOVERABLE_ERROR); }); this.eventManager_.listen(this.imaAdsManager_, google.ima.AdEvent.Type.AD_BREAK_READY, (e) => { - this.onEvent_(new shaka.util.FakeEvent( - shaka.ads.AdManager.AD_BREAK_READY, - {'originalEvent': e})); + convertEventAndSend(e, shaka.ads.AdManager.AD_BREAK_READY); }); this.eventManager_.listen(this.imaAdsManager_, google.ima.AdEvent.Type.INTERACTION, (e) => { - this.onEvent_(new shaka.util.FakeEvent( - shaka.ads.AdManager.AD_INTERACTION, - {'originalEvent': e})); + convertEventAndSend(e, shaka.ads.AdManager.AD_INTERACTION); }); } @@ -430,12 +390,12 @@ shaka.ads.ClientSideAdManager = class { const imaAd = e.getAd(); this.ad_ = new shaka.ads.ClientSideAd(imaAd, this.imaAdsManager_); - this.onEvent_(new shaka.util.FakeEvent(shaka.ads.AdManager.AD_STARTED, - { - 'ad': this.ad_, - 'sdkAdObject': imaAd, - 'originalEvent': e, - })); + const data = new Map() + .set('ad', this.ad_) + .set('sdkAdObject', imaAd) + .set('originalEvent', e); + this.onEvent_(new shaka.util.FakeEvent( + shaka.ads.AdManager.AD_STARTED, data)); if (this.ad_.isLinear()) { this.adContainer_.setAttribute('ad-active', 'true'); this.video_.pause(); @@ -448,7 +408,7 @@ shaka.ads.ClientSideAdManager = class { */ onAdComplete_(e) { this.onEvent_(new shaka.util.FakeEvent(shaka.ads.AdManager.AD_STOPPED, - {'originalEvent': e})); + (new Map()).set('originalEvent', e))); if (this.ad_.isLinear()) { this.adContainer_.removeAttribute('ad-active'); this.video_.play(); diff --git a/lib/ads/server_side_ad_manager.js b/lib/ads/server_side_ad_manager.js index f337469019..de8bbd16d8 100644 --- a/lib/ads/server_side_ad_manager.js +++ b/lib/ads/server_side_ad_manager.js @@ -80,9 +80,7 @@ shaka.ads.ServerSideAdManager = class { this.onEvent_(new shaka.util.FakeEvent( shaka.ads.AdManager.IMA_STREAM_MANAGER_LOADED, - { - 'imaStreamManager': this.streamManager_, - })); + (new Map()).set('imaStreamManager', this.streamManager_))); // Events this.eventManager_.listen(this.streamManager_, @@ -309,7 +307,7 @@ shaka.ads.ServerSideAdManager = class { } this.onEvent_(new shaka.util.FakeEvent(shaka.ads.AdManager.AD_STARTED, - {'ad': this.ad_})); + (new Map()).set('ad', this.ad_))); this.adContainer_.setAttribute('ad-active', 'true'); } @@ -335,9 +333,8 @@ shaka.ads.ServerSideAdManager = class { onLoaded_(e) { const now = Date.now() / 1000; const loadTime = now - this.streamRequestStartTime_; - this.onEvent_( - new shaka.util.FakeEvent(shaka.ads.AdManager.ADS_LOADED, - {'loadTime': loadTime})); + this.onEvent_(new shaka.util.FakeEvent(shaka.ads.AdManager.ADS_LOADED, + (new Map()).set('loadTime', loadTime))); const streamData = e.getStreamData(); const url = streamData.url; @@ -403,8 +400,8 @@ shaka.ads.ServerSideAdManager = class { this.currentCuePoints_ = cuePoints; - this.onEvent_( - new shaka.util.FakeEvent(shaka.ads.AdManager.CUEPOINTS_CHANGED, - {'cuepoints': cuePoints})); + this.onEvent_(new shaka.util.FakeEvent( + shaka.ads.AdManager.CUEPOINTS_CHANGED, + (new Map()).set('cuepoints', cuePoints))); } }; diff --git a/lib/cast/cast_proxy.js b/lib/cast/cast_proxy.js index 389c0dcaea..c453cb80ea 100644 --- a/lib/cast/cast_proxy.js +++ b/lib/cast/cast_proxy.js @@ -525,7 +525,8 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget { goog.asserts.assert(error instanceof shaka.util.Error, 'Wrong error type!'); const eventType = shaka.Player.EventName.Error; - const event = new shaka.util.FakeEvent(eventType, {'detail': error}); + const data = (new Map()).set('detail', error); + const event = new shaka.util.FakeEvent(eventType, data); this.localPlayer_.dispatchEvent(event); }); } @@ -598,7 +599,7 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget { // Convert this real Event into a FakeEvent for dispatch from our // FakeEventListener. - const fakeEvent = new shaka.util.FakeEvent(event.type, event); + const fakeEvent = shaka.util.FakeEvent.fromRealEvent(event); this.videoEventTarget_.dispatchEvent(fakeEvent); } diff --git a/lib/cast/cast_receiver.js b/lib/cast/cast_receiver.js index 1074dd6896..e5dbfb0364 100644 --- a/lib/cast/cast_receiver.js +++ b/lib/cast/cast_receiver.js @@ -407,7 +407,8 @@ shaka.cast.CastReceiver = class extends shaka.util.FakeEventTarget { goog.asserts.assert(error instanceof shaka.util.Error, 'Wrong error type!'); const eventType = shaka.Player.EventName.Error; - const event = new shaka.util.FakeEvent(eventType, {'detail': error}); + const data = (new Map()).set('detail', error); + const event = new shaka.util.FakeEvent(eventType, data); // Only dispatch the event if the player still exists. if (this.player_) { this.player_.dispatchEvent(event); diff --git a/lib/cast/cast_sender.js b/lib/cast/cast_sender.js index e7cd40e992..9e3bf90835 100644 --- a/lib/cast/cast_sender.js +++ b/lib/cast/cast_sender.js @@ -647,7 +647,7 @@ shaka.cast.CastSender = class { case 'event': { const targetName = message['targetName']; const event = message['event']; - const fakeEvent = new shaka.util.FakeEvent(event['type'], event); + const fakeEvent = shaka.util.FakeEvent.fromRealEvent(event); this.onRemoteEvent_(targetName, fakeEvent); break; } @@ -725,7 +725,7 @@ shaka.cast.CastSender = class { // Dispatch it through the Player proxy const fakeEvent = new shaka.util.FakeEvent( - 'error', {'detail': shakaError}); + 'error', (new Map()).set('detail', shakaError)); this.onRemoteEvent_('player', fakeEvent); // Force this session to disconnect and transfer playback to the local diff --git a/lib/hls/hls_parser.js b/lib/hls/hls_parser.js index c1f42d41fe..54a26174cf 100644 --- a/lib/hls/hls_parser.js +++ b/lib/hls/hls_parser.js @@ -420,18 +420,16 @@ shaka.hls.HlsParser = class { const uri = tag.getAttributeValue('URI'); const language = tag.getAttributeValue('LANGUAGE'); const value = tag.getAttributeValue('VALUE'); - const data = { - 'id': id, - }; + const data = (new Map()).set('id', id); if (uri) { - data.uri = - shaka.hls.Utils.constructAbsoluteUri(this.masterPlaylistUri_, uri); + data.set('uri', + shaka.hls.Utils.constructAbsoluteUri(this.masterPlaylistUri_, uri)); } if (language) { - data.language = language; + data.set('language', language); } if (value) { - data.value = value; + data.set('value', value); } const event = new shaka.util.FakeEvent('sessiondata', data); if (this.playerInterface_) { diff --git a/lib/media/gap_jumping_controller.js b/lib/media/gap_jumping_controller.js index e19edf5dc9..da3cfd41b5 100644 --- a/lib/media/gap_jumping_controller.js +++ b/lib/media/gap_jumping_controller.js @@ -217,8 +217,10 @@ shaka.media.GapJumpingController = class { this.didFireLargeGap_ = true; // Event firing is synchronous. - const event = new shaka.util.FakeEvent( - 'largegap', {'currentTime': currentTime, 'gapSize': jumpSize}); + const data = new Map() + .set('currentTime', currentTime) + .set('gapSize', jumpSize); + const event = new shaka.util.FakeEvent('largegap', data); event.cancelable = true; this.onEvent_(event); diff --git a/lib/media/streaming_engine.js b/lib/media/streaming_engine.js index 87f81d0943..47d489c008 100644 --- a/lib/media/streaming_engine.js +++ b/lib/media/streaming_engine.js @@ -1676,7 +1676,8 @@ shaka.media.StreamingEngine = class { // Dispatch an event to notify the application about the emsg box. const eventName = shaka.Player.EventName.Emsg; - const event = new shaka.util.FakeEvent(eventName, {'detail': emsg}); + const data = (new Map()).set('detail', emsg); + const event = new shaka.util.FakeEvent(eventName, data); this.playerInterface_.onEvent(event); } } diff --git a/lib/net/networking_engine.js b/lib/net/networking_engine.js index 5bdf87e7de..a7df748cc5 100644 --- a/lib/net/networking_engine.js +++ b/lib/net/networking_engine.js @@ -578,7 +578,8 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget { } if (error.severity == shaka.util.Error.Severity.RECOVERABLE) { - const event = new shaka.util.FakeEvent('retry', {'error': error}); + const data = (new Map()).set('error', error); + const event = new shaka.util.FakeEvent('retry', data); this.dispatchEvent(event); // Move to the next URI. diff --git a/lib/player.js b/lib/player.js index 72a9603d67..9a5bc6425e 100644 --- a/lib/player.js +++ b/lib/player.js @@ -637,7 +637,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget { enterNode: (node, has, wants) => { this.dispatchEvent(this.makeEvent_( /* name= */ shaka.Player.EventName.OnStateChange, - /* data= */ {'state': node.name})); + /* data= */ (new Map()).set('state', node.name))); const action = actions.get(node); return action(has, wants); @@ -668,7 +668,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget { onIdle: (node) => { this.dispatchEvent(this.makeEvent_( /* name= */ shaka.Player.EventName.OnStateIdle, - /* data= */ {'state': node.name})); + /* data= */ (new Map()).set('state', node.name))); }, }; @@ -688,7 +688,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget { /** * @param {!shaka.Player.EventName} name - * @param {Object=} data + * @param {Map.=} data * @return {!shaka.util.FakeEvent} * @private */ @@ -2495,12 +2495,11 @@ shaka.Player = class extends shaka.util.FakeEventTarget { goog.asserts.assert(!endTime || startTime <= endTime, 'Metadata start time should be less or equal to the end time!'); const eventName = shaka.Player.EventName.Metadata; - const data = { - startTime: startTime, - endTime: endTime, - metadataType: metadataType, - payload: payload, - }; + const data = new Map() + .set('startTime', startTime) + .set('endTime', endTime) + .set('metadataType', metadataType) + .set('payload', payload); this.dispatchEvent(this.makeEvent_(eventName, data)); } @@ -2592,23 +2591,21 @@ shaka.Player = class extends shaka.util.FakeEventTarget { const onHeadersReceived_ = (headers, request, requestType) => { // Release a 'downloadheadersreceived' event. const name = shaka.Player.EventName.DownloadHeadersReceived; - const data = { - headers, - request, - requestType, - }; + const data = new Map() + .set('headers', headers) + .set('request', request) + .set('requestType', requestType); this.dispatchEvent(this.makeEvent_(name, data)); }; /** @type {shaka.net.NetworkingEngine.OnDownloadFailed} */ const onDownloadFailed_ = (request, error, httpResponseCode, aborted) => { // Release a 'downloadfailed' event. const name = shaka.Player.EventName.DownloadFailed; - const data = { - request, - error, - httpResponseCode, - aborted, - }; + const data = new Map() + .set('request', request) + .set('error', error) + .set('httpResponseCode', httpResponseCode) + .set('aborted', aborted); this.dispatchEvent(this.makeEvent_(name, data)); }; @@ -5169,7 +5166,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget { // Surface the buffering event so that the app knows if/when we are // buffering. const eventName = shaka.Player.EventName.Buffering; - this.dispatchEvent(this.makeEvent_(eventName, {'buffering': isBuffering})); + const data = (new Map()).set('buffering', isBuffering); + this.dispatchEvent(this.makeEvent_(eventName, data)); } /** @@ -5531,10 +5529,10 @@ shaka.Player = class extends shaka.util.FakeEventTarget { onAdaptation_(from, to) { // Delay the 'adaptation' event so that StreamingEngine has time to absorb // the changes before the user tries to query it. - const event = this.makeEvent_(shaka.Player.EventName.Adaptation, { - oldTrack: from, - newTrack: to, - }); + const data = new Map() + .set('oldTrack', from) + .set('newTrack', to); + const event = this.makeEvent_(shaka.Player.EventName.Adaptation, data); this.delayDispatchEvent_(event); } @@ -5558,10 +5556,10 @@ shaka.Player = class extends shaka.util.FakeEventTarget { onVariantChanged_(from, to) { // Delay the 'variantchanged' event so StreamingEngine has time to absorb // the changes before the user tries to query it. - const event = this.makeEvent_(shaka.Player.EventName.VariantChanged, { - oldTrack: from, - newTrack: to, - }); + const data = new Map() + .set('oldTrack', from) + .set('newTrack', to); + const event = this.makeEvent_(shaka.Player.EventName.VariantChanged, data); this.delayDispatchEvent_(event); } @@ -5584,10 +5582,9 @@ shaka.Player = class extends shaka.util.FakeEventTarget { /** @private */ onAbrStatusChanged_() { - const event = this.makeEvent_(shaka.Player.EventName.AbrStatusChanged, { - newStatus: this.config_.abr.enabled, - }); - this.delayDispatchEvent_(event); + const data = (new Map()).set('newStatus', this.config_.abr.enabled); + this.delayDispatchEvent_(this.makeEvent_( + shaka.Player.EventName.AbrStatusChanged, data)); } /** @@ -5604,7 +5601,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget { } const eventName = shaka.Player.EventName.Error; - const event = this.makeEvent_(eventName, {'detail': error}); + const event = this.makeEvent_(eventName, (new Map()).set('detail', error)); this.dispatchEvent(event); if (event.defaultPrevented) { error.handled = true; @@ -5633,7 +5630,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget { eventElement: region.eventElement, }; - this.dispatchEvent(this.makeEvent_(eventName, {detail: clone})); + const data = (new Map()).set('detail', clone); + this.dispatchEvent(this.makeEvent_(eventName, data)); } /** diff --git a/lib/polyfill/orientation.js b/lib/polyfill/orientation.js index 7ce6e5c4f7..bc5561f026 100644 --- a/lib/polyfill/orientation.js +++ b/lib/polyfill/orientation.js @@ -92,7 +92,7 @@ class extends shaka.util.FakeEventTarget { /** Dispatch a 'change' event. */ dispatchChangeEvent() { - const event = new shaka.util.FakeEvent('change', {}); + const event = new shaka.util.FakeEvent('change'); this.dispatchEvent(event); } diff --git a/lib/polyfill/patchedmediakeys_apple.js b/lib/polyfill/patchedmediakeys_apple.js index e6c2b82baf..cc44b0bb2a 100644 --- a/lib/polyfill/patchedmediakeys_apple.js +++ b/lib/polyfill/patchedmediakeys_apple.js @@ -567,10 +567,10 @@ class extends shaka.util.FakeEventTarget { const isNew = this.keyStatuses.getStatus() == undefined; - const event2 = new shaka.util.FakeEvent('message', { - messageType: isNew ? 'license-request' : 'license-renewal', - message: shaka.util.BufferUtils.toArrayBuffer(event.message), - }); + const data = new Map() + .set('messageType', isNew ? 'license-request' : 'license-renewal') + .set('message', shaka.util.BufferUtils.toArrayBuffer(event.message)); + const event2 = new shaka.util.FakeEvent('message', data); this.dispatchEvent(event2); } diff --git a/lib/polyfill/patchedmediakeys_ms.js b/lib/polyfill/patchedmediakeys_ms.js index f41f8793cb..23197792fb 100644 --- a/lib/polyfill/patchedmediakeys_ms.js +++ b/lib/polyfill/patchedmediakeys_ms.js @@ -512,10 +512,10 @@ class extends shaka.util.FakeEventTarget { const isNew = this.keyStatuses.getStatus() == undefined; - const event2 = new shaka.util.FakeEvent('message', { - messageType: isNew ? 'license-request' : 'license-renewal', - message: shaka.util.BufferUtils.toArrayBuffer(event.message), - }); + const data = new Map() + .set('messageType', isNew ? 'license-request' : 'license-renewal') + .set('message', shaka.util.BufferUtils.toArrayBuffer(event.message)); + const event2 = new shaka.util.FakeEvent('message', data); this.dispatchEvent(event2); } diff --git a/lib/polyfill/patchedmediakeys_webkit.js b/lib/polyfill/patchedmediakeys_webkit.js index 22991ecdbb..343868948e 100644 --- a/lib/polyfill/patchedmediakeys_webkit.js +++ b/lib/polyfill/patchedmediakeys_webkit.js @@ -451,10 +451,10 @@ shaka.polyfill.PatchedMediaKeysWebkit.MediaKeys = class { const isNew = session.keyStatuses.getStatus() == undefined; - const event2 = new shaka.util.FakeEvent('message', { - messageType: isNew ? 'licenserequest' : 'licenserenewal', - message: event.message, - }); + const data = new Map() + .set('messageType', isNew ? 'licenserequest' : 'licenserenewal') + .set('message', event.message); + const event2 = new shaka.util.FakeEvent('message', data); session.generated(); session.dispatchEvent(event2); diff --git a/lib/util/fake_event.js b/lib/util/fake_event.js index d6f475cc2f..52ead9bd17 100644 --- a/lib/util/fake_event.js +++ b/lib/util/fake_event.js @@ -6,6 +6,8 @@ goog.provide('shaka.util.FakeEvent'); +goog.require('goog.asserts'); + /** * @summary Create an Event work-alike object based on the provided dictionary. @@ -16,18 +18,62 @@ goog.provide('shaka.util.FakeEvent'); */ shaka.util.FakeEvent = class { /** - * @param {string} type - * @param {Object=} dict + * @param {!Event} event + * @return {!shaka.util.FakeEvent} */ - constructor(type, dict = {}) { - // Take properties from dict if present. - for (const key in dict) { - Object.defineProperty(this, key, { - value: dict[key], + static fromRealEvent(event) { + const fakeEvent = new shaka.util.FakeEvent(event.type); + for (const key in event) { + Object.defineProperty(fakeEvent, key, { + value: event[key], writable: true, enumerable: true, }); } + return fakeEvent; + } + + /** + * Allows us to tell the compiler that the dictionary "map" is actually a + * generic object, for backwards compatibility. + * @param {!Map.} dict + * @return {!Object} + * @suppress {invalidCasts} + * @private + */ + static recastDictAsObject_(dict) { + goog.asserts.assert(!(dict instanceof Map), 'dict should not be a map'); + return /** @type {!Object} */ (dict); + } + + /** + * @param {string} type + * @param {Map.=} dict + */ + constructor(type, dict) { + if (dict) { + if (dict instanceof Map) { + // Take properties from dict if present. + for (const key of dict.keys()) { + Object.defineProperty(this, key, { + value: dict.get(key), + writable: true, + enumerable: true, + }); + } + } else { + // For backwards compatibility with external apps that may make use of + // this public constructor, this should still accept generic objects. + const obj = shaka.util.FakeEvent.recastDictAsObject_(dict); + for (const key in obj) { + Object.defineProperty(this, key, { + value: obj[key], + writable: true, + enumerable: true, + }); + } + } + } // The properties below cannot be set by the dict. They are all provided // for compatibility with native events. diff --git a/test/cast/cast_proxy_unit.js b/test/cast/cast_proxy_unit.js index 0fc158a82d..cb336e5a44 100644 --- a/test/cast/cast_proxy_unit.js +++ b/test/cast/cast_proxy_unit.js @@ -297,7 +297,8 @@ describe('CastProxy', () => { 'timeupdate', Util.spyFunc(proxyListener)); expect(proxyListener).not.toHaveBeenCalled(); - const fakeEvent = new FakeEvent('timeupdate', {detail: 8675309}); + const fakeEvent = new FakeEvent( + 'timeupdate', (new Map()).set('detail', 8675309)); mockVideo.on['timeupdate'](fakeEvent); expect(proxyListener).toHaveBeenCalledWith(jasmine.objectContaining({ type: 'timeupdate', @@ -315,7 +316,8 @@ describe('CastProxy', () => { mockSender.hasRemoteProperties.and.returnValue(true); expect(proxyListener).not.toHaveBeenCalled(); - const fakeEvent = new FakeEvent('timeupdate', {detail: 8675309}); + const fakeEvent = new FakeEvent( + 'timeupdate', (new Map()).set('detail', 8675309)); mockVideo.on['timeupdate'](fakeEvent); expect(proxyListener).not.toHaveBeenCalled(); }); @@ -332,7 +334,8 @@ describe('CastProxy', () => { mockSender.hasRemoteProperties.and.returnValue(true); expect(proxyListener).not.toHaveBeenCalled(); - const fakeEvent = new FakeEvent('timeupdate', {detail: 8675309}); + const fakeEvent = new FakeEvent( + 'timeupdate', (new Map()).set('detail', 8675309)); mockSender.onRemoteEvent('video', fakeEvent); expect(proxyListener).toHaveBeenCalledWith(jasmine.objectContaining({ type: 'timeupdate', @@ -446,7 +449,8 @@ describe('CastProxy', () => { 'buffering', Util.spyFunc(proxyListener)); expect(proxyListener).not.toHaveBeenCalled(); - const fakeEvent = new FakeEvent('buffering', {detail: 8675309}); + const fakeEvent = new FakeEvent( + 'buffering', (new Map()).set('detail', 8675309)); mockPlayer.listeners['buffering'](fakeEvent); expect(proxyListener).toHaveBeenCalledWith(jasmine.objectContaining({ type: 'buffering', @@ -464,7 +468,8 @@ describe('CastProxy', () => { mockSender.hasRemoteProperties.and.returnValue(true); expect(proxyListener).not.toHaveBeenCalled(); - const fakeEvent = new FakeEvent('buffering', {detail: 8675309}); + const fakeEvent = new FakeEvent( + 'buffering', (new Map()).set('detail', 8675309)); mockPlayer.listeners['buffering'](fakeEvent); expect(proxyListener).not.toHaveBeenCalled(); }); @@ -481,7 +486,8 @@ describe('CastProxy', () => { mockSender.hasRemoteProperties.and.returnValue(true); expect(proxyListener).not.toHaveBeenCalled(); - const fakeEvent = new FakeEvent('buffering', {detail: 8675309}); + const fakeEvent = new FakeEvent( + 'buffering', (new Map()).set('detail', 8675309)); mockSender.onRemoteEvent('player', fakeEvent); expect(proxyListener).toHaveBeenCalledWith(jasmine.objectContaining({ type: 'buffering', diff --git a/test/cast/cast_utils_unit.js b/test/cast/cast_utils_unit.js index 41a437889e..0688d3ef89 100644 --- a/test/cast/cast_utils_unit.js +++ b/test/cast/cast_utils_unit.js @@ -123,7 +123,7 @@ describe('CastUtils', () => { expect(typeof deserialized).toBe('object'); // The object can be used to construct a FakeEvent. - const fakeEvent = new FakeEvent(deserialized['type'], deserialized); + const fakeEvent = FakeEvent.fromRealEvent(deserialized); // The fake event has the same type and properties as the original. const asObj = /** @type {!Object} */ (fakeEvent); diff --git a/test/test/util/fake_ad_manager.js b/test/test/util/fake_ad_manager.js index 1da80c94b4..fcca89249e 100644 --- a/test/test/util/fake_ad_manager.js +++ b/test/test/util/fake_ad_manager.js @@ -85,7 +85,7 @@ shaka.test.FakeAdManager = class extends shaka.util.FakeEventTarget { */ startAd(ad) { const event = new shaka.util.FakeEvent(shaka.ads.AdManager.AD_STARTED, - {'ad': ad}); + (new Map()).set('ad', ad)); this.dispatchEvent(event); } diff --git a/test/ui/localization_unit.js b/test/ui/localization_unit.js index edb5ca5bcc..02b9f19fa8 100644 --- a/test/ui/localization_unit.js +++ b/test/ui/localization_unit.js @@ -198,7 +198,7 @@ describe('Localization', () => { localization.changeLocale([ELVISH_WOODLAND]); expect(events.length).toBe(1); - expect(events[0].locales).toEqual([ELVISH_WOODLAND]); + expect(events[0]['locales']).toEqual([ELVISH_WOODLAND]); }); @@ -214,23 +214,23 @@ describe('Localization', () => { localization.changeLocale([ELVISH_WOODLAND, DWARFISH_NORTH]); expect(events.length).toBe(1); - expect(events[0].locales).toEqual([ELVISH_WOODLAND, DWARFISH_NORTH]); + expect(events[0]['locales']).toEqual([ELVISH_WOODLAND, DWARFISH_NORTH]); // We should see an event telling us that dwarfish is still missing. localization.insert(ELVISH_WOODLAND, new Map()); localization.changeLocale([ELVISH_WOODLAND, DWARFISH_NORTH]); expect(events.length).toBe(2); - expect(events[0].locales).toEqual([ELVISH_WOODLAND, DWARFISH_NORTH]); - expect(events[1].locales).toEqual([DWARFISH_NORTH]); + expect(events[0]['locales']).toEqual([ELVISH_WOODLAND, DWARFISH_NORTH]); + expect(events[1]['locales']).toEqual([DWARFISH_NORTH]); // There should be no more events now that we added the last language. localization.insert(DWARFISH_NORTH, new Map()); localization.changeLocale([ELVISH_WOODLAND, DWARFISH_NORTH]); expect(events.length).toBe(2); - expect(events[0].locales).toEqual([ELVISH_WOODLAND, DWARFISH_NORTH]); - expect(events[1].locales).toEqual([DWARFISH_NORTH]); + expect(events[0]['locales']).toEqual([ELVISH_WOODLAND, DWARFISH_NORTH]); + expect(events[1]['locales']).toEqual([DWARFISH_NORTH]); }); }); @@ -373,8 +373,8 @@ describe('Localization', () => { // it was in the fallback (HALFLING) but not our preferred language // (EVLISH). expect(events.length).toBe(1); - expect(events[0].locales).toEqual([ELVISH_WOODLAND]); - expect(events[0].missing).toEqual(['hello']); + expect(events[0]['locales']).toEqual([ELVISH_WOODLAND]); + expect(events[0]['missing']).toEqual(['hello']); }); it('fires when key/value is missing from preferred but found in base', @@ -400,8 +400,8 @@ describe('Localization', () => { // because it was in the base (ELVISH) but not our preferred language // (EVLISH_WOODLAND). expect(events.length).toBe(1); - expect(events[0].locales).toEqual([ELVISH_WOODLAND]); - expect(events[0].missing).toEqual(['Best Wishes']); + expect(events[0]['locales']).toEqual([ELVISH_WOODLAND]); + expect(events[0]['missing']).toEqual(['Best Wishes']); }); it('fires when key/value is missing from preferred but found in sibling', @@ -427,8 +427,8 @@ describe('Localization', () => { // understand" because it was in a sibling locale (HALFLING_SHIRE) // but not our preferred language (HALFLING_COMMON). expect(events.length).toBe(1); - expect(events[0].locales).toEqual([HALFLING_COMMON]); - expect(events[0].missing).toEqual(['Do you understand']); + expect(events[0]['locales']).toEqual([HALFLING_COMMON]); + expect(events[0]['missing']).toEqual(['Do you understand']); }); it('fires when key/value is missing from some preferred languages', @@ -454,8 +454,9 @@ describe('Localization', () => { // There should have no missing localization events. expect(events.length).toBe(1); - expect(events[0].locales).toEqual([ELVISH_WOODLAND, DWARFISH_NORTH]); - expect(events[0].missing).toEqual(['may your forge burn bright']); + expect(events[0]['locales']).toEqual( + [ELVISH_WOODLAND, DWARFISH_NORTH]); + expect(events[0]['missing']).toEqual(['may your forge burn bright']); }); }); diff --git a/ui/cast_button.js b/ui/cast_button.js index 20c3680a09..c636e9ade7 100644 --- a/ui/cast_button.js +++ b/ui/cast_button.js @@ -102,9 +102,8 @@ shaka.ui.CastButton = class extends shaka.ui.Element { } catch (error) { this.castButton_.disabled = false; if (error.code != shaka.util.Error.Code.CAST_CANCELED_BY_USER) { - this.controls.dispatchEvent(new shaka.util.FakeEvent('error', { - detail: error, - })); + this.controls.dispatchEvent(new shaka.util.FakeEvent( + 'error', (new Map()).set('detail', error))); } } } diff --git a/ui/controls.js b/ui/controls.js index 0b2c83f693..a3bd3bcd8e 100644 --- a/ui/controls.js +++ b/ui/controls.js @@ -578,9 +578,8 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget { } } } catch (error) { - this.dispatchEvent(new shaka.util.FakeEvent('error', { - detail: error, - })); + this.dispatchEvent(new shaka.util.FakeEvent( + 'error', (new Map()).set('detail', error))); } } } @@ -1196,9 +1195,8 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget { /** @private */ onCastStatusChange_() { const isCasting = this.castProxy_.isCasting(); - this.dispatchEvent(new shaka.util.FakeEvent('caststatuschanged', { - newStatus: isCasting, - })); + this.dispatchEvent(new shaka.util.FakeEvent( + 'caststatuschanged', (new Map()).set('newStatus', isCasting))); if (isCasting) { this.controlsContainer_.setAttribute('casting', 'true'); diff --git a/ui/localization.js b/ui/localization.js index 013d35e9a3..fad4c1af11 100644 --- a/ui/localization.js +++ b/ui/localization.js @@ -130,28 +130,20 @@ shaka.ui.Localization = class { (locale) => !this.localizations_.has(locale)); if (missing.length) { - /** @type {shaka.ui.Localization.UnknownLocalesEvent} */ - const eMissing = { - 'locales': missing, - }; - this.events_.dispatchEvent(new shaka.util.FakeEvent( Class.UNKNOWN_LOCALES, - eMissing)); + (new Map()).set('locales', missing))); } const found = shaka.util.Iterables.filter( this.currentLocales_, (locale) => this.localizations_.has(locale)); - /** @type {shaka.ui.Localization.LocaleChangedEvent} */ - const eFound = { - 'locales': found.length ? found : [this.fallbackLocale_], - }; - + const data = (new Map()).set( + 'locales', found.length ? found : [this.fallbackLocale_]); this.events_.dispatchEvent(new shaka.util.FakeEvent( Class.LOCALE_CHANGED, - eFound)); + data)); } /** @@ -253,14 +245,11 @@ shaka.ui.Localization = class { // number of locales. Since we don't know which ones we actually checked, // just tell them the preferred locale. - /** @type {shaka.ui.Localization.UnknownLocalizationEvent} */ - const e = { - // Make a copy to avoid leaking references. - 'locales': Array.from(this.currentLocales_), - 'missing': id, - }; - - this.events_.dispatchEvent(new FakeEvent(Class.UNKNOWN_LOCALIZATION, e)); + const data = new Map() + // Make a copy to avoid leaking references. + .set('locales', Array.from(this.currentLocales_)) + .set('missing', id); + this.events_.dispatchEvent(new FakeEvent(Class.UNKNOWN_LOCALIZATION, data)); return ''; } @@ -381,18 +370,16 @@ shaka.ui.Localization = class { } if (missing.size > 0) { - /** @type {shaka.ui.Localization.MissingLocalizationsEvent} */ - const e = { - // Make a copy of the preferred locales to avoid leaking references. - 'locales': Array.from(preferredLocales), - // Because most people like arrays more than sets, convert the set to - // an array. - 'missing': Array.from(missing), - }; + const data = new Map() + // Make a copy of the preferred locales to avoid leaking references. + .set('locales', Array.from(preferredLocales)) + // Because more people like arrays more than sets, convert the set to + // an array. + .set('missing', Array.from(missing)); this.events_.dispatchEvent(new shaka.util.FakeEvent( shaka.ui.Localization.MISSING_LOCALIZATIONS, - e)); + data)); } } @@ -478,52 +465,42 @@ shaka.ui.Localization.LOCALE_CHANGED = 'locale-changed'; shaka.ui.Localization.LOCALE_UPDATED = 'locale-updated'; /** - * @typedef {{ - * 'locales': !Array. - * }} - * + * @event shaka.ui.Localization.UnknownLocalesEvent + * @property {string} type + * 'unknown-locales' * @property {!Array.} locales * The locales that the user wanted but could not be found. * @exportDoc */ -shaka.ui.Localization.UnknownLocalesEvent; /** - * @typedef {{ - * 'locales': !Array., - * 'missing': string - * }} - * + * @event shaka.ui.Localization.MissingLocalizationsEvent + * @property {string} type + * 'unknown-localization' * @property {!Array.} locales * The locales that the user wanted. * @property {string} missing * The id of the unknown entry. * @exportDoc */ -shaka.ui.Localization.UnknownLocalizationEvent; /** - * @typedef {{ - * 'locales': !Array., - * 'missing': !Array. - * }} - * + * @event shaka.ui.Localization.MissingLocalizationsEvent + * @property {string} type + * 'missing-localizations' * @property {string} locale * The locale that the user wanted. * @property {!Array.} missing * The ids of the missing entries. * @exportDoc */ -shaka.ui.Localization.MissingLocalizationsEvent; /** - * @typedef {{ - * 'locales': !Array. - * }} - * + * @event shaka.ui.Localization.LocaleChangedEvent + * @property {string} type + * 'locale-changed' * @property {!Array.} locales * The new set of locales that user wanted, * and that were successfully found. * @exportDoc */ -shaka.ui.Localization.LocaleChangedEvent; diff --git a/ui/pip_button.js b/ui/pip_button.js index 3e3f4cce48..c688d2e2cd 100644 --- a/ui/pip_button.js +++ b/ui/pip_button.js @@ -132,9 +132,8 @@ shaka.ui.PipButton = class extends shaka.ui.Element { await document.exitPictureInPicture(); } } catch (error) { - this.controls.dispatchEvent(new shaka.util.FakeEvent('error', { - detail: error, - })); + this.controls.dispatchEvent(new shaka.util.FakeEvent( + 'error', (new Map()).set('detail', error))); } }