mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
Zone.js supports the google closure compiler in the advance optimization mode, to prevent closure compiler modify the `onProperty` name such as `Element.prototype.onclick`, Zone.js implements the `onProperty` patch logic by declaring all the event names in the source code, this increases the bundle size and also require updating the event names array to keep the information updated. Now google closure compiler has the required event names defined in the built-in externs files, so zone.js can use more simple implementation and decrease the bundle size of zone.js (about 4k). PR Close #40962
92 lines
3.4 KiB
TypeScript
92 lines
3.4 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.io/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);
|
|
}
|
|
}
|