fix(zone.js): clearTimeout/clearInterval should call on object global (#37858)

Close #37333

`clearTimeout` is patched by `zone.js`, and it finally calls the native delegate of `clearTimeout`,
the current implemention only call `clearNative(id)`, but it should call on object `global` like
`clearNative.call(global, id)`. Otherwise in some env, it will throw error
`clearTimeout called on an object that does not implement interface Window`

PR Close #37858
This commit is contained in:
JiaLiPassion 2020-07-01 06:11:14 +09:00 committed by Misko Hevery
parent 253337dc0a
commit a71f114ba4
2 changed files with 22 additions and 1 deletions

View File

@ -55,7 +55,7 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam
}
function clearTask(task: Task) {
return clearNative!((<TimerOptions>task.data).handleId);
return clearNative!.call(window, (<TimerOptions>task.data).handleId);
}
setNative =

View File

@ -6,7 +6,9 @@
* found in the LICENSE file at https://angular.io/license
*/
import {patchTimer} from '../../lib/common/timers';
import {isNode, zoneSymbol} from '../../lib/common/utils';
declare const global: any;
const wtfMock = global.wtfMock;
@ -56,6 +58,25 @@ describe('setTimeout', function() {
});
});
it('should call native clearTimeout with the correct context', function() {
// since clearTimeout has been patched already, we can not test `clearTimeout` directly
// we will fake another API patch to test
let context: any = null;
const fakeGlobal = {
setTimeout: function() {
return 1;
},
clearTimeout: function(id: number) {
context = this;
}
};
patchTimer(fakeGlobal, 'set', 'clear', 'Timeout')
const cancelId = fakeGlobal.setTimeout();
const m = fakeGlobal.clearTimeout;
m.call({}, cancelId);
expect(context).toBe(fakeGlobal);
});
it('should allow cancelation of fns registered with setTimeout after invocation', function(done) {
const testZone = Zone.current.fork((Zone as any)['wtfZoneSpec']).fork({name: 'TestZone'});
testZone.run(() => {