8000 refactor(zone.js): additional cleanups to reduce code size · angular/angular@c5f01b5 · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit c5f01b5

Browse files
committed
refactor(zone.js): additional cleanups to reduce code size
NOTE: Some code paths containing special handling for IE have been removed because we no longer support IE. In this commit, we perform separate cleanups inside the zone.js package to reduce the number of `&&` operations by using optional chaining, as it makes the code smaller and more readable. The `copySymbolProperties` function is now tree-shakable in browser bundles because its implementation is only set in Node.js.
1 parent 13e3966 commit c5f01b5
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export function patchCallbacks(
1818
}
1919
const nativeDelegate = (target[symbol] = target[method]);
2020
target[method] = function (name: any, opts: any, options?: any) {
21-
if (opts && opts.prototype) {
21+
if (opts?.prototype) {
2222
callbacks.forEach(function (callback) {
2323
const source = `${targetName}.${method}::` + callback;
2424
const prototype = opts.prototype;
@@ -33,7 +33,7 @@ export function patchCallbacks(
3333
try {
3434
if (prototype.hasOwnProperty(callback)) {
3535
const descriptor = api.ObjectGetOwnPropertyDescriptor(prototype, callback);
36-
if (descriptor && descriptor.value) {
36+
if (descriptor?.value) {
3737
descriptor.value = api.wrapWithCurrentZone(descriptor.value, source);
3838
api._redefineProperty(opts.prototype, callback, descriptor);
3939
} else if (prototype[callback]) {
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export function patchBrowser(Zone: ZoneType): void {
6767
eventTargetPatch(global, api);
6868
// patch XMLHttpRequestEventTarget's addEventListener/removeEventListener
6969
const XMLHttpRequestEventTarget = (global as any)['XMLHttpRequestEventTarget'];
70-
if (XMLHttpRequestEventTarget && XMLHttpRequestEventTarget.prototype) {
70+
if (XMLHttpRequestEventTarget?.prototype) {
7171
api.patchEventTarget(global, api, [XMLHttpRequestEventTarget.prototype]);
7272
}
7373
});
@@ -255,8 +255,7 @@ export function patchBrowser(Zone: ZoneType): void {
255255
clearTask,
256256
);
257257
if (
258-
self &&
259-
self[XHR_ERROR_BEFORE_SCHEDULED] === true &&
258+
self?.[XHR_ERROR_BEFORE_SCHEDULED] === true &&
260259
!options.aborted &&
261260
task.state === SCHEDULED
262261
) {
@@ -275,12 +274,12 @@ export function patchBrowser(Zone: ZoneType): void {
275274
() =>
276275
function (self: any, args: any[]) {
277276
const task: Task = findPendingTask(self);
278-
if (task && typeof task.type == 'string') {
277+
if (typeof task?.type == 'string') {
279278
// If the XHR has already completed, do nothing.
280279
// If the XHR has already been aborted, do nothing.
281280
// Fix #569, call abort multiple times before done will cause
282281
// macroTask task count be negative number
283-
if (task.cancelFn == null || (task.data && (<XHROptions>task.data).aborted)) {
282+
if (task.cancelFn == null || (<XHROptions>task.data)?.aborted) {
284283
return;
285284
}
286285
task.zone.cancelTask(task);
@@ -298,8 +297,9 @@ export function patchBrowser(Zone: ZoneType): void {
298297

299298
Zone.__load_patch('geolocation', (global: any) => {
300299
/// GEO_LOCATION
301-
if (global['navigator'] && global['navigator'].geolocation) {
302-
patchPrototype(global['navigator'].geolocation, ['getCurrentPosition', 'watchPosition']);
300+
const geolocation = global['navigator']?.geolocation;
301+
if (geolocation) {
302+
patchPrototype(geolocation, ['getCurrentPosition', 'watchPosition']);
303303
}
304304
});
305305

Original file line numberDiff line numberDiff line change
@@ -11,11 +11,7 @@ import {ZoneType} from '../zone-impl';
1111
export function patchCanvas(Zone: ZoneType): void {
1212
Zone.__load_patch('canvas', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
1313
const HTMLCanvasElement = global['HTMLCanvasElement'];
14-
if (
15-
typeof HTMLCanvasElement !== 'undefined' &&
16-
HTMLCanvasElement.prototype &&
17-
HTMLCanvasElement.prototype.toBlob
18-
) {
14+
if (HTMLCanvasElement?.prototype?.toBlob) {
1915
api.patchMacroTask(HTMLCanvasElement.prototype, 'toBlob', (self: any, args: any[]) => {
2016
return {name: 'HTMLCanvasElement.toBlob', target: self, cbIdx: 0, args: args};
2117
});
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export function _redefineProperty(obj: any, prop: string, desc: any) {
8686
}
8787

8888
function isUnconfigurable(obj: any, prop: any) {
89-
return obj && obj[unconfigurablesKey] && obj[unconfigurablesKey][prop];
89+
return obj?.[unconfigurablesKey]?.[prop];
9090
}
9191

9292
function rewriteDescriptor(obj: any, prop: string, desc: any) {
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,21 @@ export function eventTargetPatch(_global: any, api: _ZonePrivate) {
1313
}
1414
const {eventNames, zoneSymbolEventNames, TRUE_STR, FALSE_STR, ZONE_SYMBOL_PREFIX} =
1515
api.getGlobalObjects()!;
16-
// predefine all __zone_symbol__ + eventName + true/false string
17-
for (let i = 0; i < eventNames.length; i++) {
18-
const eventName = eventNames[i];
16+
// Predefine all zone symbol event name mappings for both `capture = false` and `true`.
17+
// This avoids recomputing symbol strings at runtime and improves performance.
18+
for (const eventName of eventNames) {
1919
const falseEventName = eventName + FALSE_STR;
2020
const trueEventName = eventName + TRUE_STR;
2121
const symbol = ZONE_SYMBOL_PREFIX + falseEventName;
2222
const symbolCapture = ZONE_SYMBOL_PREFIX + trueEventName;
23-
zoneSymbolEventNames[eventName] = {};
24-
zoneSymbolEventNames[eventName][FALSE_STR] = symbol;
25-
zoneSymbolEventNames[eventName][TRUE_STR] = symbolCapture;
23+
zoneSymbolEventNames[eventName] = {[FALSE_STR]: symbol, [TRUE_STR]: symbolCapture};
2624
}
2725

28-
const EVENT_TARGET = _global['EventTarget'];
29-
if (!EVENT_TARGET || !EVENT_TARGET.prototype) {
26+
const EventTarget = _global['EventTarget'];
27+
if (!EventTarget?.prototype) {
3028
return;
3129
}
32-
api.patchEventTarget(_global, api, [EVENT_TARGET && EVENT_TARGET.prototype]);
30+
api.patchEventTarget(_global, api, [EventTarget.prototype]);
3331

3432
return true;
3533
}
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export function patchMessagePort(Zone: ZoneType): void {
1515
*/
1616
Zone.__load_patch('MessagePort', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
1717
const MessagePort = global['MessagePort'];
18-
if (typeof MessagePort !== 'undefined' && MessagePort.prototype) {
18+
if (MessagePort?.prototype) {
1919
api.patchOnProperties(MessagePort.prototype, ['message', 'messageerror']);
2020
}
2121
});
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export function propertyDescriptorPatch(api: _ZonePrivate, _global: any) {
8787
'Worker',
8888
]);
8989
const ignoreErrorProperties: IgnoreProperty[] = [];
90-
// In older browsers like IE or Edge, event handler properties (e.g., `onclick`)
90+
// In older browsers like Edge, event handler properties (e.g., `onclick`)
9191
// may not be defined directly on the `window` object but on its prototype (`WindowPrototype`).
9292
// To ensure complete coverage, we use the prototype when checking
9393
// for and patching these properties.