From a71f114ba4fae70d53a10a789f91ac93012597dd Mon Sep 17 00:00:00 2001 From: JiaLiPassion Date: Wed, 1 Jul 2020 06:11:14 +0900 Subject: [PATCH] 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 --- packages/zone.js/lib/common/timers.ts | 2 +- .../zone.js/test/common/setTimeout.spec.ts | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/packages/zone.js/lib/common/timers.ts b/packages/zone.js/lib/common/timers.ts index 50889dbc0e..e1d68b5a6d 100644 --- a/packages/zone.js/lib/common/timers.ts +++ b/packages/zone.js/lib/common/timers.ts @@ -55,7 +55,7 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam } function clearTask(task: Task) { - return clearNative!((task.data).handleId); + return clearNative!.call(window, (task.data).handleId); } setNative = diff --git a/packages/zone.js/test/common/setTimeout.spec.ts b/packages/zone.js/test/common/setTimeout.spec.ts index ed62e586ae..7d4f31eb6a 100644 --- a/packages/zone.js/test/common/setTimeout.spec.ts +++ b/packages/zone.js/test/common/setTimeout.spec.ts @@ -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(() => {