diff --git a/packages/zone.js/lib/browser/property-descriptor.ts b/packages/zone.js/lib/browser/property-descriptor.ts index e0f7b5482a5..1db4d6a3f01 100644 --- a/packages/zone.js/lib/browser/property-descriptor.ts +++ b/packages/zone.js/lib/browser/property-descriptor.ts @@ -10,14 +10,7 @@ * @suppress {globalThis} */ -import { - isBrowser, - isIE, - isMix, - isNode, - ObjectGetPrototypeOf, - patchOnProperties, -} from '../common/utils'; +import {isBrowser, isMix, isNode, ObjectGetPrototypeOf, patchOnProperties} from '../common/utils'; export interface IgnoreProperty { target: any; @@ -34,7 +27,7 @@ export function filterProperties( } const tip: IgnoreProperty[] = ignoreProperties.filter((ip) => ip.target === target); - if (!tip || tip.length === 0) { + if (tip.length === 0) { return onProperties; } @@ -93,11 +86,11 @@ export function propertyDescriptorPatch(api: _ZonePrivate, _global: any) { 'HTMLMarqueeElement', 'Worker', ]); - const ignoreErrorProperties = isIE() - ? [{target: internalWindow, ignoreProperties: ['error']}] - : []; - // in IE/Edge, onProp not exist in window object, but in WindowPrototype - // so we need to pass WindowPrototype to check onProp exist or not + const ignoreErrorProperties: IgnoreProperty[] = []; + // In older browsers like IE or Edge, event handler properties (e.g., `onclick`) + // may not be defined directly on the `window` object but on its prototype (`WindowPrototype`). + // To ensure complete coverage, we use the prototype when checking + // for and patching these properties. patchFilteredProperties( internalWindow, getOnEventNames(internalWindow), @@ -118,8 +111,7 @@ export function propertyDescriptorPatch(api: _ZonePrivate, _global: any) { ]); for (let i = 0; i < patchTargets.length; i++) { const target = _global[patchTargets[i]]; - target && - target.prototype && + target?.prototype && patchFilteredProperties( target.prototype, getOnEventNames(target.prototype), diff --git a/packages/zone.js/lib/common/utils.ts b/packages/zone.js/lib/common/utils.ts index 5b3b82281e0..bf148e4f9aa 100644 --- a/packages/zone.js/lib/common/utils.ts +++ b/packages/zone.js/lib/common/utils.ts @@ -232,8 +232,10 @@ export function patchProperty(obj: any, prop: string, prototype?: any) { } desc.set = function (this: EventSource, newValue) { - // in some of windows's onproperty callback, this is undefined - // so we need to check it + // In some versions of Windows, the `this` context may be undefined + // in on-property callbacks. + // To handle this edge case, we check if `this` is falsy and + // fallback to `_global` if needed. let target = this; if (!target && obj === _global) { target = _global; @@ -247,9 +249,10 @@ export function patchProperty(obj: any, prop: string, prototype?: any) { target.removeEventListener(eventName, wrapFn); } - // issue #978, when onload handler was added before loading zone.js - // we should remove it with originalDescSet - originalDescSet && originalDescSet.call(target, null); + // https://github.com/angular/zone.js/issues/978 + // If an inline handler (like `onload`) was defined before zone.js was loaded, + // call the original descriptor's setter to clean it up. + originalDescSet?.call(target, null); (target as any)[eventNameSymbol] = newValue; if (typeof newValue === 'function') { target.addEventListener(eventName, wrapFn, false); @@ -542,16 +545,6 @@ export function attachOriginToPatched(patched: Function, original: any) { let isDetectedIEOrEdge = false; let ieOrEdge = false; -export function isIE() { - try { - const ua = internalWindow.navigator.userAgent; - if (ua.indexOf('MSIE ') !== -1 || ua.indexOf('Trident/') !== -1) { - return true; - } - } catch (error) {} - return false; -} - export function isIEOrEdge() { if (isDetectedIEOrEdge) { return ieOrEdge; diff --git a/packages/zone.js/test/zone-spec/long-stack-trace-zone.spec.ts b/packages/zone.js/test/zone-spec/long-stack-trace-zone.spec.ts index 9e1af7c5715..f35155b2825 100644 --- a/packages/zone.js/test/zone-spec/long-stack-trace-zone.spec.ts +++ b/packages/zone.js/test/zone-spec/long-stack-trace-zone.spec.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import {isBrowser, isIE, zoneSymbol} from '../../lib/common/utils'; +import {isBrowser, zoneSymbol} from '../../lib/common/utils'; import {ifEnvSupports, isSafari, isSupportSetErrorStack} from '../test-util'; const defineProperty = (Object as any)[zoneSymbol('defineProperty')] || Object.defineProperty; @@ -119,7 +119,7 @@ describe( div.dispatchEvent(enterEvent); expect(log.length).toBe(2); - if (!isSafari() && !isIE()) { + if (!isSafari()) { expect(log[0].stack === log[1].stack).toBe(false); }