| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @license | 
					
						
							| 
									
										
										
										
											2020-05-19 12:08:49 -07:00
										 |  |  |  * Copyright Google LLC All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |  * | 
					
						
							|  |  |  |  * 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} | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  | import {isBrowser, isIE, isMix, isNode, ObjectGetPrototypeOf, patchOnProperties} from '../common/utils'; | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | const globalEventHandlersEventNames = [ | 
					
						
							|  |  |  |   'abort', | 
					
						
							|  |  |  |   'animationcancel', | 
					
						
							|  |  |  |   'animationend', | 
					
						
							|  |  |  |   'animationiteration', | 
					
						
							|  |  |  |   'auxclick', | 
					
						
							|  |  |  |   'beforeinput', | 
					
						
							|  |  |  |   'blur', | 
					
						
							|  |  |  |   'cancel', | 
					
						
							|  |  |  |   'canplay', | 
					
						
							|  |  |  |   'canplaythrough', | 
					
						
							|  |  |  |   'change', | 
					
						
							|  |  |  |   'compositionstart', | 
					
						
							|  |  |  |   'compositionupdate', | 
					
						
							|  |  |  |   'compositionend', | 
					
						
							|  |  |  |   'cuechange', | 
					
						
							|  |  |  |   'click', | 
					
						
							|  |  |  |   'close', | 
					
						
							|  |  |  |   'contextmenu', | 
					
						
							|  |  |  |   'curechange', | 
					
						
							|  |  |  |   'dblclick', | 
					
						
							|  |  |  |   'drag', | 
					
						
							|  |  |  |   'dragend', | 
					
						
							|  |  |  |   'dragenter', | 
					
						
							|  |  |  |   'dragexit', | 
					
						
							|  |  |  |   'dragleave', | 
					
						
							|  |  |  |   'dragover', | 
					
						
							|  |  |  |   'drop', | 
					
						
							|  |  |  |   'durationchange', | 
					
						
							|  |  |  |   'emptied', | 
					
						
							|  |  |  |   'ended', | 
					
						
							|  |  |  |   'error', | 
					
						
							|  |  |  |   'focus', | 
					
						
							|  |  |  |   'focusin', | 
					
						
							|  |  |  |   'focusout', | 
					
						
							|  |  |  |   'gotpointercapture', | 
					
						
							|  |  |  |   'input', | 
					
						
							|  |  |  |   'invalid', | 
					
						
							|  |  |  |   'keydown', | 
					
						
							|  |  |  |   'keypress', | 
					
						
							|  |  |  |   'keyup', | 
					
						
							|  |  |  |   'load', | 
					
						
							|  |  |  |   'loadstart', | 
					
						
							|  |  |  |   'loadeddata', | 
					
						
							|  |  |  |   'loadedmetadata', | 
					
						
							|  |  |  |   'lostpointercapture', | 
					
						
							|  |  |  |   'mousedown', | 
					
						
							|  |  |  |   'mouseenter', | 
					
						
							|  |  |  |   'mouseleave', | 
					
						
							|  |  |  |   'mousemove', | 
					
						
							|  |  |  |   'mouseout', | 
					
						
							|  |  |  |   'mouseover', | 
					
						
							|  |  |  |   'mouseup', | 
					
						
							|  |  |  |   'mousewheel', | 
					
						
							|  |  |  |   'orientationchange', | 
					
						
							|  |  |  |   'pause', | 
					
						
							|  |  |  |   'play', | 
					
						
							|  |  |  |   'playing', | 
					
						
							|  |  |  |   'pointercancel', | 
					
						
							|  |  |  |   'pointerdown', | 
					
						
							|  |  |  |   'pointerenter', | 
					
						
							|  |  |  |   'pointerleave', | 
					
						
							|  |  |  |   'pointerlockchange', | 
					
						
							|  |  |  |   'mozpointerlockchange', | 
					
						
							|  |  |  |   'webkitpointerlockerchange', | 
					
						
							|  |  |  |   'pointerlockerror', | 
					
						
							|  |  |  |   'mozpointerlockerror', | 
					
						
							|  |  |  |   'webkitpointerlockerror', | 
					
						
							|  |  |  |   'pointermove', | 
					
						
							|  |  |  |   'pointout', | 
					
						
							|  |  |  |   'pointerover', | 
					
						
							|  |  |  |   'pointerup', | 
					
						
							|  |  |  |   'progress', | 
					
						
							|  |  |  |   'ratechange', | 
					
						
							|  |  |  |   'reset', | 
					
						
							|  |  |  |   'resize', | 
					
						
							|  |  |  |   'scroll', | 
					
						
							|  |  |  |   'seeked', | 
					
						
							|  |  |  |   'seeking', | 
					
						
							|  |  |  |   'select', | 
					
						
							|  |  |  |   'selectionchange', | 
					
						
							|  |  |  |   'selectstart', | 
					
						
							|  |  |  |   'show', | 
					
						
							|  |  |  |   'sort', | 
					
						
							|  |  |  |   'stalled', | 
					
						
							|  |  |  |   'submit', | 
					
						
							|  |  |  |   'suspend', | 
					
						
							|  |  |  |   'timeupdate', | 
					
						
							|  |  |  |   'volumechange', | 
					
						
							|  |  |  |   'touchcancel', | 
					
						
							|  |  |  |   'touchmove', | 
					
						
							|  |  |  |   'touchstart', | 
					
						
							|  |  |  |   'touchend', | 
					
						
							|  |  |  |   'transitioncancel', | 
					
						
							|  |  |  |   'transitionend', | 
					
						
							|  |  |  |   'waiting', | 
					
						
							|  |  |  |   'wheel' | 
					
						
							|  |  |  | ]; | 
					
						
							|  |  |  | const documentEventNames = [ | 
					
						
							|  |  |  |   'afterscriptexecute', 'beforescriptexecute', 'DOMContentLoaded', 'freeze', 'fullscreenchange', | 
					
						
							|  |  |  |   'mozfullscreenchange', 'webkitfullscreenchange', 'msfullscreenchange', 'fullscreenerror', | 
					
						
							|  |  |  |   'mozfullscreenerror', 'webkitfullscreenerror', 'msfullscreenerror', 'readystatechange', | 
					
						
							|  |  |  |   'visibilitychange', 'resume' | 
					
						
							|  |  |  | ]; | 
					
						
							|  |  |  | const windowEventNames = [ | 
					
						
							|  |  |  |   'absolutedeviceorientation', | 
					
						
							|  |  |  |   'afterinput', | 
					
						
							|  |  |  |   'afterprint', | 
					
						
							|  |  |  |   'appinstalled', | 
					
						
							|  |  |  |   'beforeinstallprompt', | 
					
						
							|  |  |  |   'beforeprint', | 
					
						
							|  |  |  |   'beforeunload', | 
					
						
							|  |  |  |   'devicelight', | 
					
						
							|  |  |  |   'devicemotion', | 
					
						
							|  |  |  |   'deviceorientation', | 
					
						
							|  |  |  |   'deviceorientationabsolute', | 
					
						
							|  |  |  |   'deviceproximity', | 
					
						
							|  |  |  |   'hashchange', | 
					
						
							|  |  |  |   'languagechange', | 
					
						
							|  |  |  |   'message', | 
					
						
							|  |  |  |   'mozbeforepaint', | 
					
						
							|  |  |  |   'offline', | 
					
						
							|  |  |  |   'online', | 
					
						
							|  |  |  |   'paint', | 
					
						
							|  |  |  |   'pageshow', | 
					
						
							|  |  |  |   'pagehide', | 
					
						
							|  |  |  |   'popstate', | 
					
						
							|  |  |  |   'rejectionhandled', | 
					
						
							|  |  |  |   'storage', | 
					
						
							|  |  |  |   'unhandledrejection', | 
					
						
							|  |  |  |   'unload', | 
					
						
							|  |  |  |   'userproximity', | 
					
						
							| 
									
										
										
										
											2019-11-05 04:58:25 +09:00
										 |  |  |   'vrdisplayconnected', | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |   'vrdisplaydisconnected', | 
					
						
							|  |  |  |   'vrdisplaypresentchange' | 
					
						
							|  |  |  | ]; | 
					
						
							|  |  |  | const htmlElementEventNames = [ | 
					
						
							|  |  |  |   'beforecopy', 'beforecut', 'beforepaste', 'copy', 'cut', 'paste', 'dragstart', 'loadend', | 
					
						
							|  |  |  |   'animationstart', 'search', 'transitionrun', 'transitionstart', 'webkitanimationend', | 
					
						
							|  |  |  |   'webkitanimationiteration', 'webkitanimationstart', 'webkittransitionend' | 
					
						
							|  |  |  | ]; | 
					
						
							|  |  |  | const mediaElementEventNames = | 
					
						
							|  |  |  |     ['encrypted', 'waitingforkey', 'msneedkey', 'mozinterruptbegin', 'mozinterruptend']; | 
					
						
							|  |  |  | const ieElementEventNames = [ | 
					
						
							|  |  |  |   'activate', | 
					
						
							|  |  |  |   'afterupdate', | 
					
						
							|  |  |  |   'ariarequest', | 
					
						
							|  |  |  |   'beforeactivate', | 
					
						
							|  |  |  |   'beforedeactivate', | 
					
						
							|  |  |  |   'beforeeditfocus', | 
					
						
							|  |  |  |   'beforeupdate', | 
					
						
							|  |  |  |   'cellchange', | 
					
						
							|  |  |  |   'controlselect', | 
					
						
							|  |  |  |   'dataavailable', | 
					
						
							|  |  |  |   'datasetchanged', | 
					
						
							|  |  |  |   'datasetcomplete', | 
					
						
							|  |  |  |   'errorupdate', | 
					
						
							|  |  |  |   'filterchange', | 
					
						
							|  |  |  |   'layoutcomplete', | 
					
						
							|  |  |  |   'losecapture', | 
					
						
							|  |  |  |   'move', | 
					
						
							|  |  |  |   'moveend', | 
					
						
							|  |  |  |   'movestart', | 
					
						
							|  |  |  |   'propertychange', | 
					
						
							|  |  |  |   'resizeend', | 
					
						
							|  |  |  |   'resizestart', | 
					
						
							|  |  |  |   'rowenter', | 
					
						
							|  |  |  |   'rowexit', | 
					
						
							|  |  |  |   'rowsdelete', | 
					
						
							|  |  |  |   'rowsinserted', | 
					
						
							|  |  |  |   'command', | 
					
						
							|  |  |  |   'compassneedscalibration', | 
					
						
							|  |  |  |   'deactivate', | 
					
						
							|  |  |  |   'help', | 
					
						
							|  |  |  |   'mscontentzoom', | 
					
						
							|  |  |  |   'msmanipulationstatechanged', | 
					
						
							|  |  |  |   'msgesturechange', | 
					
						
							|  |  |  |   'msgesturedoubletap', | 
					
						
							|  |  |  |   'msgestureend', | 
					
						
							|  |  |  |   'msgesturehold', | 
					
						
							|  |  |  |   'msgesturestart', | 
					
						
							|  |  |  |   'msgesturetap', | 
					
						
							|  |  |  |   'msgotpointercapture', | 
					
						
							|  |  |  |   'msinertiastart', | 
					
						
							|  |  |  |   'mslostpointercapture', | 
					
						
							|  |  |  |   'mspointercancel', | 
					
						
							|  |  |  |   'mspointerdown', | 
					
						
							|  |  |  |   'mspointerenter', | 
					
						
							|  |  |  |   'mspointerhover', | 
					
						
							|  |  |  |   'mspointerleave', | 
					
						
							|  |  |  |   'mspointermove', | 
					
						
							|  |  |  |   'mspointerout', | 
					
						
							|  |  |  |   'mspointerover', | 
					
						
							|  |  |  |   'mspointerup', | 
					
						
							|  |  |  |   'pointerout', | 
					
						
							|  |  |  |   'mssitemodejumplistitemremoved', | 
					
						
							|  |  |  |   'msthumbnailclick', | 
					
						
							|  |  |  |   'stop', | 
					
						
							|  |  |  |   'storagecommit' | 
					
						
							|  |  |  | ]; | 
					
						
							|  |  |  | const webglEventNames = ['webglcontextrestored', 'webglcontextlost', 'webglcontextcreationerror']; | 
					
						
							|  |  |  | const formEventNames = ['autocomplete', 'autocompleteerror']; | 
					
						
							|  |  |  | const detailEventNames = ['toggle']; | 
					
						
							|  |  |  | const frameEventNames = ['load']; | 
					
						
							|  |  |  | const frameSetEventNames = ['blur', 'error', 'focus', 'load', 'resize', 'scroll', 'messageerror']; | 
					
						
							|  |  |  | const marqueeEventNames = ['bounce', 'finish', 'start']; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const XMLHttpRequestEventNames = [ | 
					
						
							|  |  |  |   'loadstart', 'progress', 'abort', 'error', 'load', 'progress', 'timeout', 'loadend', | 
					
						
							|  |  |  |   'readystatechange' | 
					
						
							|  |  |  | ]; | 
					
						
							|  |  |  | const IDBIndexEventNames = | 
					
						
							|  |  |  |     ['upgradeneeded', 'complete', 'abort', 'success', 'error', 'blocked', 'versionchange', 'close']; | 
					
						
							|  |  |  | const websocketEventNames = ['close', 'error', 'open', 'message']; | 
					
						
							|  |  |  | const workerEventNames = ['error', 'message']; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export const eventNames = globalEventHandlersEventNames.concat( | 
					
						
							|  |  |  |     webglEventNames, formEventNames, detailEventNames, documentEventNames, windowEventNames, | 
					
						
							|  |  |  |     htmlElementEventNames, ieElementEventNames); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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 supportsWebSocket = typeof WebSocket !== 'undefined'; | 
					
						
							|  |  |  |   const ignoreProperties: IgnoreProperty[] = _global['__Zone_ignore_on_properties']; | 
					
						
							|  |  |  |   // for browsers that we can patch the descriptor:  Chrome & Firefox
 | 
					
						
							|  |  |  |   if (isBrowser) { | 
					
						
							|  |  |  |     const internalWindow: any = window; | 
					
						
							|  |  |  |     const ignoreErrorProperties = | 
					
						
							| 
									
										
										
										
											2020-05-12 08:19:59 +01:00
										 |  |  |         isIE() ? [{target: internalWindow, ignoreProperties: ['error']}] : []; | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |     // 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, eventNames.concat(['messageerror']), | 
					
						
							|  |  |  |         ignoreProperties ? ignoreProperties.concat(ignoreErrorProperties) : ignoreProperties, | 
					
						
							|  |  |  |         ObjectGetPrototypeOf(internalWindow)); | 
					
						
							|  |  |  |     patchFilteredProperties(Document.prototype, eventNames, ignoreProperties); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (typeof internalWindow['SVGElement'] !== 'undefined') { | 
					
						
							|  |  |  |       patchFilteredProperties(internalWindow['SVGElement'].prototype, eventNames, ignoreProperties); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     patchFilteredProperties(Element.prototype, eventNames, ignoreProperties); | 
					
						
							|  |  |  |     patchFilteredProperties(HTMLElement.prototype, eventNames, ignoreProperties); | 
					
						
							|  |  |  |     patchFilteredProperties(HTMLMediaElement.prototype, mediaElementEventNames, ignoreProperties); | 
					
						
							|  |  |  |     patchFilteredProperties( | 
					
						
							|  |  |  |         HTMLFrameSetElement.prototype, windowEventNames.concat(frameSetEventNames), | 
					
						
							|  |  |  |         ignoreProperties); | 
					
						
							|  |  |  |     patchFilteredProperties( | 
					
						
							|  |  |  |         HTMLBodyElement.prototype, windowEventNames.concat(frameSetEventNames), ignoreProperties); | 
					
						
							|  |  |  |     patchFilteredProperties(HTMLFrameElement.prototype, frameEventNames, ignoreProperties); | 
					
						
							|  |  |  |     patchFilteredProperties(HTMLIFrameElement.prototype, frameEventNames, ignoreProperties); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const HTMLMarqueeElement = internalWindow['HTMLMarqueeElement']; | 
					
						
							|  |  |  |     if (HTMLMarqueeElement) { | 
					
						
							|  |  |  |       patchFilteredProperties(HTMLMarqueeElement.prototype, marqueeEventNames, ignoreProperties); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     const Worker = internalWindow['Worker']; | 
					
						
							|  |  |  |     if (Worker) { | 
					
						
							|  |  |  |       patchFilteredProperties(Worker.prototype, workerEventNames, ignoreProperties); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   const XMLHttpRequest = _global['XMLHttpRequest']; | 
					
						
							|  |  |  |   if (XMLHttpRequest) { | 
					
						
							|  |  |  |     // XMLHttpRequest is not available in ServiceWorker, so we need to check here
 | 
					
						
							|  |  |  |     patchFilteredProperties(XMLHttpRequest.prototype, XMLHttpRequestEventNames, ignoreProperties); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   const XMLHttpRequestEventTarget = _global['XMLHttpRequestEventTarget']; | 
					
						
							|  |  |  |   if (XMLHttpRequestEventTarget) { | 
					
						
							|  |  |  |     patchFilteredProperties( | 
					
						
							|  |  |  |         XMLHttpRequestEventTarget && XMLHttpRequestEventTarget.prototype, XMLHttpRequestEventNames, | 
					
						
							|  |  |  |         ignoreProperties); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (typeof IDBIndex !== 'undefined') { | 
					
						
							|  |  |  |     patchFilteredProperties(IDBIndex.prototype, IDBIndexEventNames, ignoreProperties); | 
					
						
							|  |  |  |     patchFilteredProperties(IDBRequest.prototype, IDBIndexEventNames, ignoreProperties); | 
					
						
							|  |  |  |     patchFilteredProperties(IDBOpenDBRequest.prototype, IDBIndexEventNames, ignoreProperties); | 
					
						
							|  |  |  |     patchFilteredProperties(IDBDatabase.prototype, IDBIndexEventNames, ignoreProperties); | 
					
						
							|  |  |  |     patchFilteredProperties(IDBTransaction.prototype, IDBIndexEventNames, ignoreProperties); | 
					
						
							|  |  |  |     patchFilteredProperties(IDBCursor.prototype, IDBIndexEventNames, ignoreProperties); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (supportsWebSocket) { | 
					
						
							|  |  |  |     patchFilteredProperties(WebSocket.prototype, websocketEventNames, ignoreProperties); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |