Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

WIP(core): Proposal: can unload, reload patch modules #1159

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions karma-build-jasmine-scope.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* @license
* Copyright Google Inc. 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
*/

module.exports = function(config) {
config.client.preload = 'build/test/browser-scope-zone-preload.js';
require('./karma-build-jasmine.conf.js')(config);
config.client.entrypoint = 'browser_scope_zone_entry_point';
config.client.setup = 'browser-scope-zone-setup';
config.client.notPatchTestFramework = true;
};
4 changes: 4 additions & 0 deletions karma-build.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
*/

module.exports = function(config) {
var preload = config.client.preload;
require('./karma-base.conf.js')(config);
if (preload) {
config.files.push(preload);
}
config.files.push('build/test/wtf_mock.js');
config.files.push('build/test/test_fake_polyfill.js');
config.files.push('build/lib/zone.js');
Expand Down
3 changes: 2 additions & 1 deletion lib/browser/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import {findEventTasks} from '../common/events';
import {patchTimer} from '../common/timers';
import {bindArguments, patchClass, patchMacroTask, patchMethod, patchOnProperties, patchPrototype, scheduleMacroTaskWithCurrentZone, ZONE_SYMBOL_ADD_EVENT_LISTENER, ZONE_SYMBOL_REMOVE_EVENT_LISTENER, zoneSymbol} from '../common/utils';
import {attachOriginToPatched, bindArguments, patchClass, patchMacroTask, patchMethod, patchOnProperties, patchPrototype, scheduleMacroTaskWithCurrentZone, ZONE_SYMBOL_ADD_EVENT_LISTENER, ZONE_SYMBOL_REMOVE_EVENT_LISTENER, zoneSymbol} from '../common/utils';

import {propertyPatch} from './define-property';
import {eventTargetPatch, patchEvent} from './event-target';
Expand All @@ -23,6 +23,7 @@ Zone.__load_patch('util', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
api.patchOnProperties = patchOnProperties;
api.patchMethod = patchMethod;
api.bindArguments = bindArguments;
api.attachOriginToPatched = attachOriginToPatched;
});

Zone.__load_patch('timers', (global: any) => {
Expand Down
2 changes: 1 addition & 1 deletion lib/browser/register-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function patchCallbacks(target: any, targetName: string, method: string, callbac
return nativeDelegate.call(target, name, opts, options);
};

attachOriginToPatched(target[method], nativeDelegate);
attachOriginToPatched(target, method, nativeDelegate);
}

export function registerElementPatch(_global: any) {
Expand Down
2 changes: 2 additions & 0 deletions lib/browser/webapis-user-media.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Zone.__load_patch('getUserMedia', (global: any, Zone: any, api: _ZonePrivate) =>
}
let navigator = global['navigator'];
if (navigator && navigator.getUserMedia) {
const native = navigator.getUserMedia;
navigator.getUserMedia = wrapFunctionArgs(navigator.getUserMedia);
api.attachOriginToPatched(navigator, 'getUserMedia', native);
}
});
1 change: 1 addition & 0 deletions lib/browser/websocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export function apply(api: _ZonePrivate, _global: any) {
};

const globalWebSocket = _global['WebSocket'];
api.attachOriginToPatched(_global, 'WebSocket', WS);
for (const prop in WS) {
globalWebSocket[prop] = WS[prop];
}
Expand Down
8 changes: 4 additions & 4 deletions lib/common/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -621,13 +621,13 @@ export function patchEventTarget(
};

// for native toString patch
attachOriginToPatched(proto[ADD_EVENT_LISTENER], nativeAddEventListener);
attachOriginToPatched(proto[REMOVE_EVENT_LISTENER], nativeRemoveEventListener);
attachOriginToPatched(proto, ADD_EVENT_LISTENER, nativeAddEventListener);
attachOriginToPatched(proto, REMOVE_EVENT_LISTENER, nativeRemoveEventListener);
if (nativeRemoveAllListeners) {
attachOriginToPatched(proto[REMOVE_ALL_LISTENERS_EVENT_LISTENER], nativeRemoveAllListeners);
attachOriginToPatched(proto, REMOVE_ALL_LISTENERS_EVENT_LISTENER, nativeRemoveAllListeners);
}
if (nativeListeners) {
attachOriginToPatched(proto[LISTENERS_EVENT_LISTENER], nativeListeners);
attachOriginToPatched(proto, LISTENERS_EVENT_LISTENER, nativeListeners);
}
return true;
}
Expand Down
3 changes: 2 additions & 1 deletion lib/common/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Zone.__load_patch('fetch', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
signal.abortController = abortController;
return abortController;
};
global['AbortController'].prototype = OriginalAbortController.prototype;
abortNative = api.patchMethod(
OriginalAbortController.prototype, 'abort',
(delegate: Function) => (self: any, args: any) => {
Expand Down Expand Up @@ -97,4 +98,4 @@ Zone.__load_patch('fetch', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
}
});
};
});
});
19 changes: 14 additions & 5 deletions lib/common/promise.ts
Original file line number Diff line number Diff line change
Expand Up @@ -408,12 +408,18 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr
const NativePromise = global[symbolPromise] = global['Promise'];
const ZONE_AWARE_PROMISE = Zone.__symbol__('ZoneAwarePromise');

let desc = ObjectGetOwnPropertyDescriptor(global, 'Promise');
if (!desc || desc.configurable) {
desc && delete desc.writable;
desc && delete desc.value;
if (!desc) {
let desc = null;
const originalDesc = ObjectGetOwnPropertyDescriptor(global, 'Promise');
if (!originalDesc || originalDesc.configurable) {
if (!originalDesc) {
desc = {configurable: true, enumerable: true};
} else {
desc = {
configurable: originalDesc.configurable,
enumerable: originalDesc.enumerable,
get: originalDesc.get,
set: originalDesc.set
};
}
desc.get = function() {
// if we already set ZoneAwarePromise, use patched one
Expand Down Expand Up @@ -442,9 +448,11 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr
};

ObjectDefineProperty(global, 'Promise', desc);
(Zone as any).__register_patched_delegate(global, 'Promise', originalDesc, true);
}

global['Promise'] = ZoneAwarePromise;
api.attachOriginToPatched(global, 'Promise', NativePromise);

const symbolThenPatched = __symbol__('thenPatched');

Expand All @@ -469,6 +477,7 @@ Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePr
return wrapped.then(onResolve, onReject);
};
(Ctor as any)[symbolThenPatched] = true;
api.attachOriginToPatched(Ctor.prototype, 'then', originalThen);
}

api.patchThen = patchThen;
Expand Down
29 changes: 21 additions & 8 deletions lib/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ export function patchPrototype(prototype: any, fnNames: string[]) {
const patched: any = function() {
return delegate.apply(this, bindArguments(<any>arguments, source + '.' + name));
};
attachOriginToPatched(patched, delegate);
return patched;
})(delegate);
attachOriginToPatched(prototype, name, delegate);
}
}
}
Expand Down Expand Up @@ -159,13 +159,23 @@ const wrapFn = function(event: Event) {
};

export function patchProperty(obj: any, prop: string, prototype?: any) {
let desc = ObjectGetOwnPropertyDescriptor(obj, prop);
if (!desc && prototype) {
let desc: PropertyDescriptor|null = null;
const originalDesc = ObjectGetOwnPropertyDescriptor(obj, prop);
if (!originalDesc && prototype) {
// when patch window object, use prototype to check prop exist or not
const prototypeDesc = ObjectGetOwnPropertyDescriptor(prototype, prop);
if (prototypeDesc) {
desc = {enumerable: true, configurable: true};
}
} else if (originalDesc) {
desc = {
configurable: originalDesc.configurable,
enumerable: originalDesc.enumerable,
value: originalDesc.value,
writable: originalDesc.writable,
get: originalDesc.get,
set: originalDesc.set
};
}
// if the descriptor not exists or is not configurable
// just return
Expand Down Expand Up @@ -262,6 +272,8 @@ export function patchProperty(obj: any, prop: string, prototype?: any) {
ObjectDefineProperty(obj, prop, desc);

obj[onPropPatchedSymbol] = true;

(Zone as any).__register_patched_delegate(obj, prop, originalDesc, true);
}

export function patchOnProperties(obj: any, properties: string[]|null, prototype?: any) {
Expand Down Expand Up @@ -315,7 +327,7 @@ export function patchClass(className: string) {
};

// attach original delegate to patched function
attachOriginToPatched(_global[className], OriginalClass);
attachOriginToPatched(_global, className, OriginalClass);

const instance = new OriginalClass(function() {});

Expand All @@ -336,7 +348,7 @@ export function patchClass(className: string) {
// keep callback in wrapped function so we can
// use it in Function.prototype.toString to return
// the native one.
attachOriginToPatched(this[originalInstanceKey][prop], fn);
attachOriginToPatched(this[originalInstanceKey], prop, fn);
} else {
this[originalInstanceKey][prop] = fn;
}
Expand Down Expand Up @@ -411,7 +423,7 @@ export function patchMethod(
proto[name] = function() {
return patchDelegate(this, arguments as any);
};
attachOriginToPatched(proto[name], delegate);
attachOriginToPatched(proto, name, delegate);
if (shouldCopySymbolProperties) {
copySymbolProperties(delegate, proto[name]);
}
Expand Down Expand Up @@ -483,8 +495,9 @@ export function patchMicroTask(
});
}

export function attachOriginToPatched(patched: Function, original: any) {
(patched as any)[zoneSymbol('OriginalDelegate')] = original;
export function attachOriginToPatched(patchedTarget: any, prop: string, original: any) {
patchedTarget[prop][zoneSymbol('OriginalDelegate')] = original;
(Zone as any).__register_patched_delegate(patchedTarget, prop, original);
}

let isDetectedIEOrEdge = false;
Expand Down
Loading