mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
129 lines
3.5 KiB
TypeScript
129 lines
3.5 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,
|
|
isIE,
|
|
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 || 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',
|
|
]);
|
|
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
|
|
patchFilteredProperties(
|
|
internalWindow,
|
|
getOnEventNames(internalWindow),
|
|
ignoreProperties ? ignoreProperties.concat(ignoreErrorProperties) : 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 &&
|
|
target.prototype &&
|
|
patchFilteredProperties(
|
|
target.prototype,
|
|
getOnEventNames(target.prototype),
|
|
ignoreProperties,
|
|
);
|
|
}
|
|
}
|