diff --git a/lib/browser/browser.ts b/lib/browser/browser.ts index d4873797a..03a26758a 100644 --- a/lib/browser/browser.ts +++ b/lib/browser/browser.ts @@ -12,7 +12,7 @@ import {findEventTasks} from '../common/events'; import {patchTimer} from '../common/timers'; -import {bindArguments, patchClass, patchMacroTask, patchMethod, patchOnProperties, patchPrototype, scheduleMacroTaskWithCurrentZone, ZONE_SYMBOL_ADD_EVENT_LISTENER, ZONE_SYMBOL_REMOVE_EVENT_LISTENER, zoneSymbol} from '../common/utils'; +import {bindArguments, patchClass, patchMacroTask, patchMethod, patchOnProperties, patchPrototype, scheduleMacroTaskWithCurrentZone, ZONE_SYMBOL_ADD_EVENT_LISTENER, ZONE_SYMBOL_REMOVE_EVENT_LISTENER, zoneSymbol, createConstructorFunctionWrapper, createShallowObjectCopy, ObjectGetPrototypeOf} from '../common/utils'; import {propertyPatch} from './define-property'; import {eventTargetPatch, patchEvent} from './event-target'; @@ -58,6 +58,15 @@ Zone.__load_patch('EventTarget', (global: any, Zone: ZoneType, api: _ZonePrivate (Zone as any)[SYMBOL_BLACK_LISTED_EVENTS] = global[SYMBOL_BLACK_LISTED_EVENTS]; } + global['Event'] = createConstructorFunctionWrapper(global['Event']); + global['EventTarget'] = createConstructorFunctionWrapper(global['EventTarget']); + + if (global['XMLHttpRequestEventTarget'] && global['XMLHttpRequestEventTarget'].prototype) { + const XMLHttpRequestEventTargetProtoProto = createShallowObjectCopy(ObjectGetPrototypeOf(global['XMLHttpRequestEventTarget'].prototype)); + global['XMLHttpRequestEventTarget'] = createConstructorFunctionWrapper(global['XMLHttpRequestEventTarget']); + (Object as any).setPrototypeOf(global['XMLHttpRequestEventTarget'].prototype, XMLHttpRequestEventTargetProtoProto); + } + patchEvent(global, api); eventTargetPatch(global, api); // patch XMLHttpRequestEventTarget's addEventListener/removeEventListener @@ -78,6 +87,8 @@ Zone.__load_patch('on_property', (global: any, Zone: ZoneType, api: _ZonePrivate }); Zone.__load_patch('canvas', (global: any) => { + global['HTMLCanvasElement'] = createConstructorFunctionWrapper(global['HTMLCanvasElement']); + const HTMLCanvasElement = global['HTMLCanvasElement']; if (typeof HTMLCanvasElement !== 'undefined' && HTMLCanvasElement.prototype && HTMLCanvasElement.prototype.toBlob) { diff --git a/lib/common/utils.ts b/lib/common/utils.ts index e7bbed307..da75bcc23 100644 --- a/lib/common/utils.ts +++ b/lib/common/utils.ts @@ -484,3 +484,30 @@ export function isIEOrEdge() { } catch (error) { } } + +export function createShallowObjectCopy(obj: Object) { + const wrapper = ObjectCreate(obj); + + Object.getOwnPropertyNames(obj).forEach((key: string) => { + const desc = Object.getOwnPropertyDescriptor(obj, key); + if (desc) { + Object.defineProperty(wrapper, key, desc); + } + }); + + return wrapper; +} + +export function createConstructorFunctionWrapper(fn: Function | ObjectConstructor) { + if (typeof fn !== 'function') { + return fn; + } + + const wrappedFn = function(...args: any[]) { + return new (fn as any)(...args); + } + + wrappedFn.prototype = createShallowObjectCopy(fn.prototype); + + return wrappedFn; +}