angular/packages/zone.js/lib/browser/property-descriptor.ts
Matthieu Riegler 2e4659648a refactor(zone.js): remove legacy browser support (#63511)
This commit removes the support for legacy browsers.

BREAKING CHANGE: IE/Non-Chromium Edge are not supported anymore.

PR Close #63511
2025-10-16 14:58:45 +00:00

116 lines
3.1 KiB
TypeScript

/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
/**
* @fileoverview
* @suppress {globalThis}
*/
import {isBrowser, isMix, isNode, ObjectGetPrototypeOf, patchOnProperties} from '../common/utils';
export interface IgnoreProperty {
target: any;
ignoreProperties: string[];
}
export function filterProperties(
target: any,
onProperties: string[],
ignoreProperties: IgnoreProperty[],
): string[] {
if (!ignoreProperties || ignoreProperties.length === 0) {
return onProperties;
}
const tip: IgnoreProperty[] = ignoreProperties.filter((ip) => ip.target === target);
if (tip.length === 0) {
return onProperties;
}
const targetIgnoreProperties: string[] = tip[0].ignoreProperties;
return onProperties.filter((op) => targetIgnoreProperties.indexOf(op) === -1);
}
export function patchFilteredProperties(
target: any,
onProperties: string[],
ignoreProperties: IgnoreProperty[],
prototype?: any,
) {
// check whether target is available, sometimes target will be undefined
// because different browser or some 3rd party plugin.
if (!target) {
return;
}
const filteredProperties: string[] = filterProperties(target, onProperties, ignoreProperties);
patchOnProperties(target, filteredProperties, prototype);
}
/**
* Get all event name properties which the event name startsWith `on`
* from the target object itself, inherited properties are not considered.
*/
export function getOnEventNames(target: Object) {
return Object.getOwnPropertyNames(target)
.filter((name) => name.startsWith('on') && name.length > 2)
.map((name) => name.substring(2));
}
export function propertyDescriptorPatch(api: _ZonePrivate, _global: any) {
if (isNode && !isMix) {
return;
}
if ((Zone as any)[api.symbol('patchEvents')]) {
// events are already been patched by legacy patch.
return;
}
const ignoreProperties: IgnoreProperty[] = _global['__Zone_ignore_on_properties'];
// for browsers that we can patch the descriptor: Chrome & Firefox
let patchTargets: string[] = [];
if (isBrowser) {
const internalWindow: any = window;
patchTargets = patchTargets.concat([
'Document',
'SVGElement',
'Element',
'HTMLElement',
'HTMLBodyElement',
'HTMLMediaElement',
'HTMLFrameSetElement',
'HTMLFrameElement',
'HTMLIFrameElement',
'HTMLMarqueeElement',
'Worker',
]);
patchFilteredProperties(
internalWindow,
getOnEventNames(internalWindow),
ignoreProperties,
ObjectGetPrototypeOf(internalWindow),
);
}
patchTargets = patchTargets.concat([
'XMLHttpRequest',
'XMLHttpRequestEventTarget',
'IDBIndex',
'IDBRequest',
'IDBOpenDBRequest',
'IDBDatabase',
'IDBTransaction',
'IDBCursor',
'WebSocket',
]);
for (let i = 0; i < patchTargets.length; i++) {
const target = _global[patchTargets[i]];
target?.prototype &&
patchFilteredProperties(
target.prototype,
getOnEventNames(target.prototype),
ignoreProperties,
);
}
}