@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import {globalSources, patchEventPrototype, patchEventTarget, zoneSymbolEventNames} from '../common/events';
|
||||
import {ADD_EVENT_LISTENER_STR, ArraySlice, FALSE_STR, ObjectCreate, ObjectDefineProperty, ObjectGetOwnPropertyDescriptor, REMOVE_EVENT_LISTENER_STR, TRUE_STR, ZONE_SYMBOL_PREFIX, attachOriginToPatched, bindArguments, isBrowser, isIEOrEdge, isMix, isNode, patchClass, patchMacroTask, patchMethod, patchOnProperties, wrapWithCurrentZone} from '../common/utils';
|
||||
import {ADD_EVENT_LISTENER_STR, ArraySlice, attachOriginToPatched, bindArguments, FALSE_STR, isBrowser, isIEOrEdge, isMix, isNode, ObjectCreate, ObjectDefineProperty, ObjectGetOwnPropertyDescriptor, patchClass, patchMacroTask, patchMethod, patchOnProperties, REMOVE_EVENT_LISTENER_STR, TRUE_STR, wrapWithCurrentZone, ZONE_SYMBOL_PREFIX} from '../common/utils';
|
||||
|
||||
import {patchCallbacks} from './browser-util';
|
||||
import {eventNames, filterProperties} from './property-descriptor';
|
||||
@ -45,7 +45,17 @@ Zone.__load_patch('util', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
|
||||
api.attachOriginToPatched = attachOriginToPatched;
|
||||
api._redefineProperty = Object.defineProperty;
|
||||
api.patchCallbacks = patchCallbacks;
|
||||
api.getGlobalObjects = () =>
|
||||
({globalSources, zoneSymbolEventNames, eventNames, isBrowser, isMix, isNode, TRUE_STR,
|
||||
FALSE_STR, ZONE_SYMBOL_PREFIX, ADD_EVENT_LISTENER_STR, REMOVE_EVENT_LISTENER_STR});
|
||||
api.getGlobalObjects = () => ({
|
||||
globalSources,
|
||||
zoneSymbolEventNames,
|
||||
eventNames,
|
||||
isBrowser,
|
||||
isMix,
|
||||
isNode,
|
||||
TRUE_STR,
|
||||
FALSE_STR,
|
||||
ZONE_SYMBOL_PREFIX,
|
||||
ADD_EVENT_LISTENER_STR,
|
||||
REMOVE_EVENT_LISTENER_STR
|
||||
});
|
||||
});
|
||||
|
@ -16,23 +16,25 @@ import {propertyDescriptorLegacyPatch} from './property-descriptor-legacy';
|
||||
import {registerElementPatch} from './register-element';
|
||||
|
||||
(function(_global: any) {
|
||||
const symbolPrefix = _global['__Zone_symbol_prefix'] || '__zone_symbol__';
|
||||
function __symbol__(name: string) { return symbolPrefix + name; }
|
||||
_global[__symbol__('legacyPatch')] = function() {
|
||||
const Zone = _global['Zone'];
|
||||
Zone.__load_patch('defineProperty', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
|
||||
api._redefineProperty = _redefineProperty;
|
||||
propertyPatch();
|
||||
});
|
||||
Zone.__load_patch('registerElement', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
|
||||
registerElementPatch(global, api);
|
||||
});
|
||||
const symbolPrefix = _global['__Zone_symbol_prefix'] || '__zone_symbol__';
|
||||
function __symbol__(name: string) {
|
||||
return symbolPrefix + name;
|
||||
}
|
||||
_global[__symbol__('legacyPatch')] = function() {
|
||||
const Zone = _global['Zone'];
|
||||
Zone.__load_patch('defineProperty', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
|
||||
api._redefineProperty = _redefineProperty;
|
||||
propertyPatch();
|
||||
});
|
||||
Zone.__load_patch('registerElement', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
|
||||
registerElementPatch(global, api);
|
||||
});
|
||||
|
||||
Zone.__load_patch('EventTargetLegacy', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
|
||||
eventTargetLegacyPatch(global, api);
|
||||
propertyDescriptorLegacyPatch(api, global);
|
||||
});
|
||||
};
|
||||
Zone.__load_patch('EventTargetLegacy', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
|
||||
eventTargetLegacyPatch(global, api);
|
||||
propertyDescriptorLegacyPatch(api, global);
|
||||
});
|
||||
};
|
||||
})(typeof window !== 'undefined' ?
|
||||
window :
|
||||
typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {});
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
import {findEventTasks} from '../common/events';
|
||||
import {patchTimer} from '../common/timers';
|
||||
import {ZONE_SYMBOL_ADD_EVENT_LISTENER, ZONE_SYMBOL_REMOVE_EVENT_LISTENER, patchClass, patchMethod, patchPrototype, scheduleMacroTaskWithCurrentZone, zoneSymbol} from '../common/utils';
|
||||
import {patchClass, patchMethod, patchPrototype, scheduleMacroTaskWithCurrentZone, ZONE_SYMBOL_ADD_EVENT_LISTENER, ZONE_SYMBOL_REMOVE_EVENT_LISTENER, zoneSymbol} from '../common/utils';
|
||||
|
||||
import {patchCustomElements} from './custom-elements';
|
||||
import {eventTargetPatch, patchEvent} from './event-target';
|
||||
@ -99,7 +99,9 @@ Zone.__load_patch('XHR', (global: any, Zone: ZoneType) => {
|
||||
}
|
||||
const XMLHttpRequestPrototype: any = XMLHttpRequest.prototype;
|
||||
|
||||
function findPendingTask(target: any) { return target[XHR_TASK]; }
|
||||
function findPendingTask(target: any) {
|
||||
return target[XHR_TASK];
|
||||
}
|
||||
|
||||
let oriAddListener = XMLHttpRequestPrototype[ZONE_SYMBOL_ADD_EVENT_LISTENER];
|
||||
let oriRemoveListener = XMLHttpRequestPrototype[ZONE_SYMBOL_REMOVE_EVENT_LISTENER];
|
||||
@ -170,7 +172,7 @@ Zone.__load_patch('XHR', (global: any, Zone: ZoneType) => {
|
||||
if (!storedTask) {
|
||||
target[XHR_TASK] = task;
|
||||
}
|
||||
sendNative !.apply(target, data.args);
|
||||
sendNative!.apply(target, data.args);
|
||||
target[XHR_SCHEDULED] = true;
|
||||
return task;
|
||||
}
|
||||
@ -182,14 +184,14 @@ Zone.__load_patch('XHR', (global: any, Zone: ZoneType) => {
|
||||
// Note - ideally, we would call data.target.removeEventListener here, but it's too late
|
||||
// to prevent it from firing. So instead, we store info for the event listener.
|
||||
data.aborted = true;
|
||||
return abortNative !.apply(data.target, data.args);
|
||||
return abortNative!.apply(data.target, data.args);
|
||||
}
|
||||
|
||||
const openNative =
|
||||
patchMethod(XMLHttpRequestPrototype, 'open', () => function(self: any, args: any[]) {
|
||||
self[XHR_SYNC] = args[2] == false;
|
||||
self[XHR_URL] = args[1];
|
||||
return openNative !.apply(self, args);
|
||||
return openNative!.apply(self, args);
|
||||
});
|
||||
|
||||
const XMLHTTPREQUEST_SOURCE = 'XMLHttpRequest.send';
|
||||
@ -201,11 +203,11 @@ Zone.__load_patch('XHR', (global: any, Zone: ZoneType) => {
|
||||
// a fetch is scheduling, so we are using xhr to polyfill fetch
|
||||
// and because we already schedule macroTask for fetch, we should
|
||||
// not schedule a macroTask for xhr again
|
||||
return sendNative !.apply(self, args);
|
||||
return sendNative!.apply(self, args);
|
||||
}
|
||||
if (self[XHR_SYNC]) {
|
||||
// if the XHR is sync there is no task to schedule, just execute the code.
|
||||
return sendNative !.apply(self, args);
|
||||
return sendNative!.apply(self, args);
|
||||
} else {
|
||||
const options: XHROptions =
|
||||
{target: self, url: self[XHR_URL], isPeriodic: false, args: args, aborted: false};
|
||||
@ -235,7 +237,7 @@ Zone.__load_patch('XHR', (global: any, Zone: ZoneType) => {
|
||||
task.zone.cancelTask(task);
|
||||
} else if ((Zone.current as any)[fetchTaskAborting] === true) {
|
||||
// the abort is called from fetch polyfill, we need to call native abort of XHR.
|
||||
return abortNative !.apply(self, args);
|
||||
return abortNative!.apply(self, args);
|
||||
}
|
||||
// Otherwise, we are trying to abort an XHR which has not yet been sent, so there is no
|
||||
// task
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
export function patchCustomElements(_global: any, api: _ZonePrivate) {
|
||||
const {isBrowser, isMix} = api.getGlobalObjects() !;
|
||||
const {isBrowser, isMix} = api.getGlobalObjects()!;
|
||||
if ((!isBrowser && !isMix) || !_global['customElements'] || !('customElements' in _global)) {
|
||||
return;
|
||||
}
|
||||
|
@ -36,7 +36,9 @@ export function propertyPatch() {
|
||||
};
|
||||
|
||||
Object.defineProperties = function(obj, props) {
|
||||
Object.keys(props).forEach(function(prop) { Object.defineProperty(obj, prop, props[prop]); });
|
||||
Object.keys(props).forEach(function(prop) {
|
||||
Object.defineProperty(obj, prop, props[prop]);
|
||||
});
|
||||
return obj;
|
||||
};
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
export function eventTargetLegacyPatch(_global: any, api: _ZonePrivate) {
|
||||
const {eventNames, globalSources, zoneSymbolEventNames, TRUE_STR, FALSE_STR, ZONE_SYMBOL_PREFIX} =
|
||||
api.getGlobalObjects() !;
|
||||
api.getGlobalObjects()!;
|
||||
const WTF_ISSUE_555 =
|
||||
'Anchor,Area,Audio,BR,Base,BaseFont,Body,Button,Canvas,Content,DList,Directory,Div,Embed,FieldSet,Font,Form,Frame,FrameSet,HR,Head,Heading,Html,IFrame,Image,Input,Keygen,LI,Label,Legend,Link,Map,Marquee,Media,Menu,Meta,Meter,Mod,OList,Object,OptGroup,Option,Output,Paragraph,Pre,Progress,Quote,Script,Select,Source,Span,Style,TableCaption,TableCell,TableCol,Table,TableRow,TableSection,TextArea,Title,Track,UList,Unknown,Video';
|
||||
const NO_EVENT_TARGET =
|
||||
|
@ -12,7 +12,7 @@ export function eventTargetPatch(_global: any, api: _ZonePrivate) {
|
||||
return;
|
||||
}
|
||||
const {eventNames, zoneSymbolEventNames, TRUE_STR, FALSE_STR, ZONE_SYMBOL_PREFIX} =
|
||||
api.getGlobalObjects() !;
|
||||
api.getGlobalObjects()!;
|
||||
// predefine all __zone_symbol__ + eventName + true/false string
|
||||
for (let i = 0; i < eventNames.length; i++) {
|
||||
const eventName = eventNames[i];
|
||||
|
@ -13,7 +13,7 @@
|
||||
import * as webSocketPatch from './websocket';
|
||||
|
||||
export function propertyDescriptorLegacyPatch(api: _ZonePrivate, _global: any) {
|
||||
const {isNode, isMix} = api.getGlobalObjects() !;
|
||||
const {isNode, isMix} = api.getGlobalObjects()!;
|
||||
if (isNode && !isMix) {
|
||||
return;
|
||||
}
|
||||
@ -31,7 +31,7 @@ export function propertyDescriptorLegacyPatch(api: _ZonePrivate, _global: any) {
|
||||
}
|
||||
|
||||
function canPatchViaPropertyDescriptor(api: _ZonePrivate, _global: any) {
|
||||
const {isBrowser, isMix} = api.getGlobalObjects() !;
|
||||
const {isBrowser, isMix} = api.getGlobalObjects()!;
|
||||
if ((isBrowser || isMix) &&
|
||||
!api.ObjectGetOwnPropertyDescriptor(HTMLElement.prototype, 'onclick') &&
|
||||
typeof Element !== 'undefined') {
|
||||
@ -42,9 +42,13 @@ function canPatchViaPropertyDescriptor(api: _ZonePrivate, _global: any) {
|
||||
// try to use onclick to detect whether we can patch via propertyDescriptor
|
||||
// because XMLHttpRequest is not available in service worker
|
||||
if (desc) {
|
||||
api.ObjectDefineProperty(
|
||||
Element.prototype, 'onclick',
|
||||
{enumerable: true, configurable: true, get: function() { return true; }});
|
||||
api.ObjectDefineProperty(Element.prototype, 'onclick', {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
get: function() {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
const div = document.createElement('div');
|
||||
const result = !!div.onclick;
|
||||
api.ObjectDefineProperty(Element.prototype, 'onclick', desc);
|
||||
@ -70,9 +74,13 @@ function canPatchViaPropertyDescriptor(api: _ZonePrivate, _global: any) {
|
||||
// and if XMLHttpRequest.prototype.onreadystatechange is undefined,
|
||||
// we should set a real desc instead a fake one
|
||||
if (xhrDesc) {
|
||||
api.ObjectDefineProperty(
|
||||
XMLHttpRequestPrototype, ON_READY_STATE_CHANGE,
|
||||
{enumerable: true, configurable: true, get: function() { return true; }});
|
||||
api.ObjectDefineProperty(XMLHttpRequestPrototype, ON_READY_STATE_CHANGE, {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
get: function() {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
const req = new XMLHttpRequest();
|
||||
const result = !!req.onreadystatechange;
|
||||
// restore original desc
|
||||
@ -83,8 +91,12 @@ function canPatchViaPropertyDescriptor(api: _ZonePrivate, _global: any) {
|
||||
api.ObjectDefineProperty(XMLHttpRequestPrototype, ON_READY_STATE_CHANGE, {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
get: function() { return this[SYMBOL_FAKE_ONREADYSTATECHANGE]; },
|
||||
set: function(value) { this[SYMBOL_FAKE_ONREADYSTATECHANGE] = value; }
|
||||
get: function() {
|
||||
return this[SYMBOL_FAKE_ONREADYSTATECHANGE];
|
||||
},
|
||||
set: function(value) {
|
||||
this[SYMBOL_FAKE_ONREADYSTATECHANGE] = value;
|
||||
}
|
||||
});
|
||||
const req = new XMLHttpRequest();
|
||||
const detectFunc = () => {};
|
||||
@ -99,7 +111,7 @@ function canPatchViaPropertyDescriptor(api: _ZonePrivate, _global: any) {
|
||||
// for `onwhatever` properties and replace them with zone-bound functions
|
||||
// - Chrome (for now)
|
||||
function patchViaCapturingAllTheEvents(api: _ZonePrivate) {
|
||||
const {eventNames} = api.getGlobalObjects() !;
|
||||
const {eventNames} = api.getGlobalObjects()!;
|
||||
const unboundKey = api.symbol('unbound');
|
||||
for (let i = 0; i < eventNames.length; i++) {
|
||||
const property = eventNames[i];
|
||||
|
@ -10,7 +10,7 @@
|
||||
* @suppress {globalThis}
|
||||
*/
|
||||
|
||||
import {ObjectGetPrototypeOf, isBrowser, isIE, isMix, isNode, patchOnProperties} from '../common/utils';
|
||||
import {isBrowser, isIE, isMix, isNode, ObjectGetPrototypeOf, patchOnProperties} from '../common/utils';
|
||||
|
||||
const globalEventHandlersEventNames = [
|
||||
'abort',
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
export function registerElementPatch(_global: any, api: _ZonePrivate) {
|
||||
const {isBrowser, isMix} = api.getGlobalObjects() !;
|
||||
const {isBrowser, isMix} = api.getGlobalObjects()!;
|
||||
if ((!isBrowser && !isMix) || !('registerElement' in (<any>_global).document)) {
|
||||
return;
|
||||
}
|
||||
|
@ -83,7 +83,9 @@ Zone.__load_patch('ResizeObserver', (global: any, Zone: any, api: _ZonePrivate)
|
||||
ResizeObserver.prototype, 'disconnect', (delegate: Function) => (self: any, args: any[]) => {
|
||||
const targets = self[resizeObserverSymbol];
|
||||
if (targets) {
|
||||
targets.forEach((target: any) => { target[resizeObserverSymbol] = undefined; });
|
||||
targets.forEach((target: any) => {
|
||||
target[resizeObserverSymbol] = undefined;
|
||||
});
|
||||
self[resizeObserverSymbol] = undefined;
|
||||
}
|
||||
return delegate.apply(self, args);
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
// we have to patch the instance since the proto is non-configurable
|
||||
export function apply(api: _ZonePrivate, _global: any) {
|
||||
const {ADD_EVENT_LISTENER_STR, REMOVE_EVENT_LISTENER_STR} = api.getGlobalObjects() !;
|
||||
const {ADD_EVENT_LISTENER_STR, REMOVE_EVENT_LISTENER_STR} = api.getGlobalObjects()!;
|
||||
const WS = (<any>_global).WebSocket;
|
||||
// On Safari window.EventTarget doesn't exist so need to patch WS add/removeEventListener
|
||||
// On older Chrome, no need since EventTarget was already patched
|
||||
|
Reference in New Issue
Block a user