| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 (function() { | 
|  | 2 | 
|  | 3     // This polyfill fixes the following problems with Edge browser | 
|  | 4     // (1) Various maplike methods for keystatuses are not supported or suported
      incorrectly | 
|  | 5     // (2) Key Ids exposed in keystatuses are incorrect (byte swaps) | 
|  | 6     if ( navigator.userAgent.toLowerCase().indexOf('edge') > -1 ) { | 
|  | 7         ////////////////////////////////////////////////////////////////////////
     /////////////////////// | 
|  | 8         // The following function is the core of this JS patch. The rest of this
      file is infrastructure | 
|  | 9         // required to enable this function | 
|  | 10         ////////////////////////////////////////////////////////////////////////
     /////////////////////// | 
|  | 11         function _proxyKeyStatusesChange( event ) { | 
|  | 12             this._keyStatuses.clear(); | 
|  | 13             var keyStatuses = []; | 
|  | 14             this._session.keyStatuses.forEach( function( keyId, status ) { | 
|  | 15                 var newKeyId = new Uint8Array( keyId ); | 
|  | 16 | 
|  | 17                 function swap( arr, a, b ) { var t = arr[a]; arr[a] = arr[b]; ar
     r[b] = t; } | 
|  | 18                 swap( newKeyId, 0, 3 ); | 
|  | 19                 swap( newKeyId, 1, 2 ); | 
|  | 20                 swap( newKeyId, 4, 5 ); | 
|  | 21                 swap( newKeyId, 6, 7 ); | 
|  | 22 | 
|  | 23                 keyStatuses.push( { key: newKeyId, status: status, ord: arrayBuf
     ferAsString( newKeyId ) } ); | 
|  | 24             }); | 
|  | 25 | 
|  | 26             function lexicographical( a, b ) { return a < b ? -1 : a === b ? 0 :
      +1; } | 
|  | 27             function lexicographicalkey( a, b ) { return lexicographical( a.ord,
      b.ord ); } | 
|  | 28 | 
|  | 29             keyStatuses.sort( lexicographicalkey ).forEach( function( obj ) { | 
|  | 30                 this._keyStatuses._set( obj.key, obj.status ); | 
|  | 31             }.bind( this ) ); | 
|  | 32 | 
|  | 33             this.dispatchEvent( event ); | 
|  | 34         }; | 
|  | 35         ////////////////////////////////////////////////////////////////////////
     /////////////////////// | 
|  | 36 | 
|  | 37         // Override MediaKeys.createSession | 
|  | 38         var _mediaKeysCreateSession = MediaKeys.prototype.createSession; | 
|  | 39         MediaKeys.prototype.createSession = function ( sessionType ) { | 
|  | 40             return new MediaKeySession( _mediaKeysCreateSession.call( this, sess
     ionType ) ); | 
|  | 41         }; | 
|  | 42 | 
|  | 43         // MediaKeySession proxy | 
|  | 44         function MediaKeySession( session ) { | 
|  | 45             EventTarget.call( this ); | 
|  | 46             this._session = session; | 
|  | 47             this._keyStatuses = new MediaKeyStatusMap(); | 
|  | 48             this._session.addEventListener("keystatuseschange",this._onKeyStatus
     esChange.bind(this)); | 
|  | 49             this._session.addEventListener("message",this.dispatchEvent.bind(thi
     s)); | 
|  | 50         } | 
|  | 51 | 
|  | 52         MediaKeySession.prototype = Object.create( EventTarget.prototype ); | 
|  | 53 | 
|  | 54         Object.defineProperties( MediaKeySession.prototype, { | 
|  | 55             sessionId:  { get: function() { return this._session.sessionId; } }, | 
|  | 56             expiration: { get: function() { return this._session.expiration; } }
     , | 
|  | 57             closed:     { get: function() { return this._session.closed; } }, | 
|  | 58             keyStatuses:{ get: function() { return this._keyStatuses; } } | 
|  | 59         }); | 
|  | 60 | 
|  | 61         [ "generateRequest", "load", "update", "remove", "close" ].forEach( func
     tion( fnname ) { | 
|  | 62             MediaKeySession.prototype[ fnname ] = function() { | 
|  | 63                 return window.MediaKeySession.prototype[ fnname ].apply( this._s
     ession, arguments ); | 
|  | 64             } | 
|  | 65         } ); | 
|  | 66 | 
|  | 67         MediaKeySession.prototype._onKeyStatusesChange = _proxyKeyStatusesChange
     ; | 
|  | 68 | 
|  | 69         // MediaKeyStatusMap proxy | 
|  | 70         // | 
|  | 71         // We need a proxy class to replace the broken MediaKeyStatusMap one. We
      cannot use a | 
|  | 72         // regular Map directly because we need get and has methods to compare b
     y value not | 
|  | 73         // as references. | 
|  | 74         function MediaKeyStatusMap() { this._map = new Map(); } | 
|  | 75 | 
|  | 76         Object.defineProperties( MediaKeyStatusMap.prototype, { | 
|  | 77             size:               { get: function() { return this._map.size; } }, | 
|  | 78             forEach:            { get: function() { return function( f ) { retur
     n this._map.forEach( f ); } } }, | 
|  | 79             entries:            { get: function() { return function() { return t
     his._map.entries(); } } }, | 
|  | 80             values:             { get: function() { return function() { return t
     his._map.values(); } } }, | 
|  | 81             keys:               { get: function() { return function() { return t
     his._map.keys(); } } }, | 
|  | 82             clear:              { get: function() { return function() { return t
     his._map.clear(); } } } } ); | 
|  | 83 | 
|  | 84         MediaKeyStatusMap.prototype[ Symbol.iterator ] = function() { return thi
     s._map[ Symbol.iterator ]() }; | 
|  | 85 | 
|  | 86         MediaKeyStatusMap.prototype.has = function has( keyId ) { | 
|  | 87             for ( var k of this._map.keys() ) { if ( arrayBufferEqual( k, keyId 
     ) ) return true; } | 
|  | 88             return false; | 
|  | 89         }; | 
|  | 90 | 
|  | 91         MediaKeyStatusMap.prototype.get = function get( keyId ) { | 
|  | 92             for ( var k of this._map.entries() ) { if ( arrayBufferEqual( k[ 0 ]
     , keyId ) ) return k[ 1 ]; } | 
|  | 93         }; | 
|  | 94 | 
|  | 95         MediaKeyStatusMap.prototype._set = function _set( keyId, status ) { | 
|  | 96             this._map.set( new Uint8Array( keyId ), status ); | 
|  | 97         }; | 
|  | 98 | 
|  | 99         function arrayBufferEqual(buf1, buf2) | 
|  | 100         { | 
|  | 101             if (buf1.byteLength !== buf2.byteLength) return false; | 
|  | 102             var a1 = Array.from( new Int8Array(buf1) ), a2 = Array.from( new Int
     8Array(buf2) ); | 
|  | 103             return a1.every( function( x, i ) { return x === a2[i]; } ); | 
|  | 104         } | 
|  | 105 | 
|  | 106         // EventTarget | 
|  | 107         function EventTarget(){ | 
|  | 108             this.listeners = {}; | 
|  | 109         }; | 
|  | 110 | 
|  | 111         EventTarget.prototype.listeners = null; | 
|  | 112 | 
|  | 113         EventTarget.prototype.addEventListener = function(type, callback){ | 
|  | 114             if(!(type in this.listeners)) { | 
|  | 115                 this.listeners[type] = []; | 
|  | 116             } | 
|  | 117             this.listeners[type].push(callback); | 
|  | 118         }; | 
|  | 119 | 
|  | 120         EventTarget.prototype.removeEventListener = function(type, callback){ | 
|  | 121             if(!(type in this.listeners)) { | 
|  | 122                 return; | 
|  | 123             } | 
|  | 124             var stack = this.listeners[type]; | 
|  | 125             for(var i = 0, l = stack.length; i < l; i++){ | 
|  | 126                 if(stack[i] === callback){ | 
|  | 127                     stack.splice(i, 1); | 
|  | 128                     return this.removeEventListener(type, callback); | 
|  | 129                 } | 
|  | 130             } | 
|  | 131         }; | 
|  | 132 | 
|  | 133         EventTarget.prototype.dispatchEvent = function(event){ | 
|  | 134             if(!(event.type in this.listeners)) { | 
|  | 135                 return; | 
|  | 136             } | 
|  | 137             var stack = this.listeners[event.type]; | 
|  | 138             event.target = this; | 
|  | 139             for(var i = 0, l = stack.length; i < l; i++) { | 
|  | 140                 stack[i].call(this, event); | 
|  | 141             } | 
|  | 142         }; | 
|  | 143     } | 
|  | 144 })(); | 
| OLD | NEW | 
|---|