@@ -331,3 +331,93 @@ export function patchNativeScriptEventTarget(global: any, api: _ZonePrivate, api
331331
332332 return results ;
333333}
334+
335+ const _global = global ;
336+
337+ const zoneSymbol = Zone . __symbol__ ;
338+
339+ const originalInstanceKey = zoneSymbol ( 'originalInstance' ) ;
340+
341+ function getAllPropertyNames ( obj : unknown ) {
342+ const props = new Set < string > ( ) ;
343+
344+ do {
345+ Object . getOwnPropertyNames ( obj ) . forEach ( ( prop ) => {
346+ props . add ( prop ) ;
347+ } ) ;
348+ } while ( ( obj = Object . getPrototypeOf ( obj ) ) && obj !== Object . prototype ) ;
349+
350+ return Array . from ( props ) ;
351+ }
352+
353+ // wrap some native API on `window`
354+ export function patchClass ( className : string , api : _ZonePrivate ) {
355+ const OriginalClass = _global [ className ] ;
356+ if ( ! OriginalClass ) return ;
357+ // keep original class in global
358+ _global [ zoneSymbol ( className ) ] = OriginalClass ;
359+
360+ _global [ className ] = function ( ) {
361+ const a = api . bindArguments ( < any > arguments , className ) ;
362+ switch ( a . length ) {
363+ case 0 :
364+ this [ originalInstanceKey ] = new OriginalClass ( ) ;
365+ break ;
366+ case 1 :
367+ this [ originalInstanceKey ] = new OriginalClass ( a [ 0 ] ) ;
368+ break ;
369+ case 2 :
370+ this [ originalInstanceKey ] = new OriginalClass ( a [ 0 ] , a [ 1 ] ) ;
371+ break ;
372+ case 3 :
373+ this [ originalInstanceKey ] = new OriginalClass ( a [ 0 ] , a [ 1 ] , a [ 2 ] ) ;
374+ break ;
375+ case 4 :
376+ this [ originalInstanceKey ] = new OriginalClass ( a [ 0 ] , a [ 1 ] , a [ 2 ] , a [ 3 ] ) ;
377+ break ;
378+ default :
379+ throw new Error ( 'Arg list too long.' ) ;
380+ }
381+ } ;
382+
383+ // attach original delegate to patched function
384+ api . attachOriginToPatched ( _global [ className ] , OriginalClass ) ;
385+
386+ const instance = new OriginalClass ( function ( ) { } ) ;
387+
388+ let prop ;
389+ for ( prop of Object . getOwnPropertyNames ( instance ) ) {
390+ // https://bugs.webkit.org/show_bug.cgi?id=44721
391+ if ( className === 'XMLHttpRequest' && prop === 'responseBlob' ) continue ;
392+ ( function ( prop ) {
393+ if ( typeof instance [ prop ] === 'function' ) {
394+ _global [ className ] . prototype [ prop ] = function ( ) {
395+ return this [ originalInstanceKey ] [ prop ] . apply ( this [ originalInstanceKey ] , arguments ) ;
396+ } ;
397+ } else {
398+ api . ObjectDefineProperty ( _global [ className ] . prototype , prop , {
399+ set : function ( fn ) {
400+ if ( typeof fn === 'function' ) {
401+ this [ originalInstanceKey ] [ prop ] = api . wrapWithCurrentZone ( fn , className + '.' + prop ) ;
402+ // keep callback in wrapped function so we can
403+ // use it in Function.prototype.toString to return
404+ // the native one.
405+ api . attachOriginToPatched ( this [ originalInstanceKey ] [ prop ] , fn ) ;
406+ } else {
407+ this [ originalInstanceKey ] [ prop ] = fn ;
408+ }
409+ } ,
410+ get : function ( ) {
411+ return this [ originalInstanceKey ] [ prop ] ;
412+ } ,
413+ } ) ;
414+ }
415+ } ) ( prop ) ;
416+ }
417+
418+ for ( prop in Object . getOwnPropertyNames ( OriginalClass ) ) {
419+ if ( prop !== 'prototype' && OriginalClass . hasOwnProperty ( prop ) ) {
420+ _global [ className ] [ prop ] = OriginalClass [ prop ] ;
421+ }
422+ }
423+ }
0 commit comments