'use strict'; /** * @license Angular v * (c) 2010-2022 Google LLC. https://angular.io/ * License: MIT */ /* * This is necessary for Chrome and Chrome mobile, to enable * things like redefining `createdCallback` on an element. */ let zoneSymbol; let _defineProperty; let _getOwnPropertyDescriptor; let _create; let unconfigurablesKey; function propertyPatch() { zoneSymbol = Zone.__symbol__; _defineProperty = Object[zoneSymbol('defineProperty')] = Object.defineProperty; _getOwnPropertyDescriptor = Object[zoneSymbol('getOwnPropertyDescriptor')] = Object.getOwnPropertyDescriptor; _create = Object.create; unconfigurablesKey = zoneSymbol('unconfigurables'); Object.defineProperty = function (obj, prop, desc) { if (isUnconfigurable(obj, prop)) { throw new TypeError('Cannot assign to read only property \'' + prop + '\' of ' + obj); } const originalConfigurableFlag = desc.configurable; if (prop !== 'prototype') { desc = rewriteDescriptor(obj, prop, desc); } return _tryDefineProperty(obj, prop, desc, originalConfigurableFlag); }; Object.defineProperties = function (obj, props) { Object.keys(props).forEach(function (prop) { Object.defineProperty(obj, prop, props[prop]); }); for (const sym of Object.getOwnPropertySymbols(props)) { const desc = Object.getOwnPropertyDescriptor(props, sym); // Since `Object.getOwnPropertySymbols` returns *all* symbols, // including non-enumerable ones, retrieve property descriptor and check // enumerability there. Proceed with the rewrite only when a property is // enumerable to make the logic consistent with the way regular // properties are retrieved (via `Object.keys`, which respects // `enumerable: false` flag). More information: // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties#retrieval if (desc?.enumerable) { Object.defineProperty(obj, sym, props[sym]); } } return obj; }; Object.create = function (proto, propertiesObject) { if (typeof propertiesObject === 'object' && !Object.isFrozen(propertiesObject)) { Object.keys(propertiesObject).forEach(function (prop) { propertiesObject[prop] = rewriteDescriptor(proto, prop, propertiesObject[prop]); }); } return _create(proto, propertiesObject); }; Object.getOwnPropertyDescriptor = function (obj, prop) { const desc = _getOwnPropertyDescriptor(obj, prop); if (desc && isUnconfigurable(obj, prop)) { desc.configurable = false; } return desc; }; } function _redefineProperty(obj, prop, desc) { const originalConfigurableFlag = desc.configurable; desc = rewriteDescriptor(obj, prop, desc); return _tryDefineProperty(obj, prop, desc, originalConfigurableFlag); } function isUnconfigurable(obj, prop) { return obj && obj[unconfigurablesKey] && obj[unconfigurablesKey][prop]; } function rewriteDescriptor(obj, prop, desc) { // issue-927, if the desc is frozen, don't try to change the desc if (!Object.isFrozen(desc)) { desc.configurable = true; } if (!desc.configurable) { // issue-927, if the obj is frozen, don't try to set the desc to obj if (!obj[unconfigurablesKey] && !Object.isFrozen(obj)) { _defineProperty(obj, unconfigurablesKey, { writable: true, value: {} }); } if (obj[unconfigurablesKey]) { obj[unconfigurablesKey][prop] = true; } } return desc; } function _tryDefineProperty(obj, prop, desc, originalConfigurableFlag) { try { return _defineProperty(obj, prop, desc); } catch (error) { if (desc.configurable) { // In case of errors, when the configurable flag was likely set by rewriteDescriptor(), // let's retry with the original flag value if (typeof originalConfigurableFlag == 'undefined') { delete desc.configurable; } else { desc.configurable = originalConfigurableFlag; } try { return _defineProperty(obj, prop, desc); } catch (error) { let swallowError = false; if (prop === 'createdCallback' || prop === 'attachedCallback' || prop === 'detachedCallback' || prop === 'attributeChangedCallback') { // We only swallow the error in registerElement patch // this is the work around since some applications // fail if we throw the error swallowError = true; } if (!swallowError) { throw error; } // TODO: @JiaLiPassion, Some application such as `registerElement` patch // still need to swallow the error, in the future after these applications // are updated, the following logic can be removed. let descJson = null; try { descJson = JSON.stringify(desc); } catch (error) { descJson = desc.toString(); } console.log(`Attempting to configure '${prop}' with descriptor '${descJson}' on object '${obj}' and got error, giving up: ${error}`); } } else { throw error; } } } function eventTargetLegacyPatch(_global, api) { const { eventNames, globalSources, zoneSymbolEventNames, TRUE_STR, FALSE_STR, ZONE_SYMBOL_PREFIX } = 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 = 'ApplicationCache,EventSource,FileReader,InputMethodContext,MediaController,MessagePort,Node,Performance,SVGElementInstance,SharedWorker,TextTrack,TextTrackCue,TextTrackList,WebKitNamedFlow,Window,Worker,WorkerGlobalScope,XMLHttpRequest,XMLHttpRequestEventTarget,XMLHttpRequestUpload,IDBRequest,IDBOpenDBRequest,IDBDatabase,IDBTransaction,IDBCursor,DBIndex,WebSocket' .split(','); const EVENT_TARGET = 'EventTarget'; let apis = []; const isWtf = _global['wtf']; const WTF_ISSUE_555_ARRAY = WTF_ISSUE_555.split(','); if (isWtf) { // Workaround for: https://github.com/google/tracing-framework/issues/555 apis = WTF_ISSUE_555_ARRAY.map((v) => 'HTML' + v + 'Element').concat(NO_EVENT_TARGET); } else if (_global[EVENT_TARGET]) { apis.push(EVENT_TARGET); } else { // Note: EventTarget is not available in all browsers, // if it's not available, we instead patch the APIs in the IDL that inherit from EventTarget apis = NO_EVENT_TARGET; } const isDisableIECheck = _global['__Zone_disable_IE_check'] || false; const isEnableCrossContextCheck = _global['__Zone_enable_cross_context_check'] || false; const ieOrEdge = api.isIEOrEdge(); const ADD_EVENT_LISTENER_SOURCE = '.addEventListener:'; const FUNCTION_WRAPPER = '[object FunctionWrapper]'; const BROWSER_TOOLS = 'function __BROWSERTOOLS_CONSOLE_SAFEFUNC() { [native code] }'; const pointerEventsMap = { 'MSPointerCancel': 'pointercancel', 'MSPointerDown': 'pointerdown', 'MSPointerEnter': 'pointerenter', 'MSPointerHover': 'pointerhover', 'MSPointerLeave': 'pointerleave', 'MSPointerMove': 'pointermove', 'MSPointerOut': 'pointerout', 'MSPointerOver': 'pointerover', 'MSPointerUp': 'pointerup' }; // predefine all __zone_symbol__ + eventName + true/false string for (let i = 0; i < eventNames.length; i++) { const eventName = eventNames[i]; const falseEventName = eventName + FALSE_STR; const trueEventName = eventName + TRUE_STR; const symbol = ZONE_SYMBOL_PREFIX + falseEventName; const symbolCapture = ZONE_SYMBOL_PREFIX + trueEventName; zoneSymbolEventNames[eventName] = {}; zoneSymbolEventNames[eventName][FALSE_STR] = symbol; zoneSymbolEventNames[eventName][TRUE_STR] = symbolCapture; } // predefine all task.source string for (let i = 0; i < WTF_ISSUE_555_ARRAY.length; i++) { const target = WTF_ISSUE_555_ARRAY[i]; const targets = globalSources[target] = {}; for (let j = 0; j < eventNames.length; j++) { const eventName = eventNames[j]; targets[eventName] = target + ADD_EVENT_LISTENER_SOURCE + eventName; } } const checkIEAndCrossContext = function (nativeDelegate, delegate, target, args) { if (!isDisableIECheck && ieOrEdge) { if (isEnableCrossContextCheck) { try { const testString = delegate.toString(); if ((testString === FUNCTION_WRAPPER || testString == BROWSER_TOOLS)) { nativeDelegate.apply(target, args); return false; } } catch (error) { nativeDelegate.apply(target, args); return false; } } else { const testString = delegate.toString(); if ((testString === FUNCTION_WRAPPER || testString == BROWSER_TOOLS)) { nativeDelegate.apply(target, args); return false; } } } else if (isEnableCrossContextCheck) { try { delegate.toString(); } catch (error) { nativeDelegate.apply(target, args); return false; } } return true; }; const apiTypes = []; for (let i = 0; i < apis.length; i++) { const type = _global[apis[i]]; apiTypes.push(type && type.prototype); } // vh is validateHandler to check event handler // is valid or not(for security check) api.patchEventTarget(_global, api, apiTypes, { vh: checkIEAndCrossContext, transferEventName: (eventName) => { const pointerEventName = pointerEventsMap[eventName]; return pointerEventName || eventName; } }); Zone[api.symbol('patchEventTarget')] = !!_global[EVENT_TARGET]; return true; } // we have to patch the instance since the proto is non-configurable function apply(api, _global) { const { ADD_EVENT_LISTENER_STR, REMOVE_EVENT_LISTENER_STR } = api.getGlobalObjects(); const WS = _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 if (!_global.EventTarget) { api.patchEventTarget(_global, api, [WS.prototype]); } _global.WebSocket = function (x, y) { const socket = arguments.length > 1 ? new WS(x, y) : new WS(x); let proxySocket; let proxySocketProto; // Safari 7.0 has non-configurable own 'onmessage' and friends properties on the socket instance const onmessageDesc = api.ObjectGetOwnPropertyDescriptor(socket, 'onmessage'); if (onmessageDesc && onmessageDesc.configurable === false) { proxySocket = api.ObjectCreate(socket); // socket have own property descriptor 'onopen', 'onmessage', 'onclose', 'onerror' // but proxySocket not, so we will keep socket as prototype and pass it to // patchOnProperties method proxySocketProto = socket; [ADD_EVENT_LISTENER_STR, REMOVE_EVENT_LISTENER_STR, 'send', 'close'].forEach(function (propName) { proxySocket[propName] = function () { const args = api.ArraySlice.call(arguments); if (propName === ADD_EVENT_LISTENER_STR || propName === REMOVE_EVENT_LISTENER_STR) { const eventName = args.length > 0 ? args[0] : undefined; if (eventName) { const propertySymbol = Zone.__symbol__('ON_PROPERTY' + eventName); socket[propertySymbol] = proxySocket[propertySymbol]; } } return socket[propName].apply(socket, args); }; }); } else { // we can patch the real socket proxySocket = socket; } api.patchOnProperties(proxySocket, ['close', 'error', 'message', 'open'], proxySocketProto); return proxySocket; }; const globalWebSocket = _global['WebSocket']; for (const prop in WS) { globalWebSocket[prop] = WS[prop]; } } /** * @fileoverview * @suppress {globalThis} */ function propertyDescriptorLegacyPatch(api, _global) { const { isNode, isMix } = api.getGlobalObjects(); if (isNode && !isMix) { return; } if (!canPatchViaPropertyDescriptor(api, _global)) { const supportsWebSocket = typeof WebSocket !== 'undefined'; // Safari, Android browsers (Jelly Bean) patchViaCapturingAllTheEvents(api); api.patchClass('XMLHttpRequest'); if (supportsWebSocket) { apply(api, _global); } Zone[api.symbol('patchEvents')] = true; } } function canPatchViaPropertyDescriptor(api, _global) { const { isBrowser, isMix } = api.getGlobalObjects(); if ((isBrowser || isMix) && !api.ObjectGetOwnPropertyDescriptor(HTMLElement.prototype, 'onclick') && typeof Element !== 'undefined') { // WebKit https://bugs.webkit.org/show_bug.cgi?id=134364 // IDL interface attributes are not configurable const desc = api.ObjectGetOwnPropertyDescriptor(Element.prototype, 'onclick'); if (desc && !desc.configurable) return false; // 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; } }); const div = document.createElement('div'); const result = !!div.onclick; api.ObjectDefineProperty(Element.prototype, 'onclick', desc); return result; } } const XMLHttpRequest = _global['XMLHttpRequest']; if (!XMLHttpRequest) { // XMLHttpRequest is not available in service worker return false; } const ON_READY_STATE_CHANGE = 'onreadystatechange'; const XMLHttpRequestPrototype = XMLHttpRequest.prototype; const xhrDesc = api.ObjectGetOwnPropertyDescriptor(XMLHttpRequestPrototype, ON_READY_STATE_CHANGE); // add enumerable and configurable here because in opera // by default XMLHttpRequest.prototype.onreadystatechange is undefined // without adding enumerable and configurable will cause onreadystatechange // non-configurable // 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; } }); const req = new XMLHttpRequest(); const result = !!req.onreadystatechange; // restore original desc api.ObjectDefineProperty(XMLHttpRequestPrototype, ON_READY_STATE_CHANGE, xhrDesc || {}); return result; } else { const SYMBOL_FAKE_ONREADYSTATECHANGE = api.symbol('fake'); 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; } }); const req = new XMLHttpRequest(); const detectFunc = () => { }; req.onreadystatechange = detectFunc; const result = req[SYMBOL_FAKE_ONREADYSTATECHANGE] === detectFunc; req.onreadystatechange = null; return result; } } 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', 'vrdisplayconnected', 'vrdisplaydisconnected', 'vrdisplaypresentchange' ]; const htmlElementEventNames = [ 'beforecopy', 'beforecut', 'beforepaste', 'copy', 'cut', 'paste', 'dragstart', 'loadend', 'animationstart', 'search', 'transitionrun', 'transitionstart', 'webkitanimationend', 'webkitanimationiteration', 'webkitanimationstart', 'webkittransitionend' ]; 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 eventNames = [ ...globalEventHandlersEventNames, ...webglEventNames, ...formEventNames, ...detailEventNames, ...documentEventNames, ...windowEventNames, ...htmlElementEventNames, ...ieElementEventNames ]; // Whenever any eventListener fires, we check the eventListener target and all parents // for `onwhatever` properties and replace them with zone-bound functions // - Chrome (for now) function patchViaCapturingAllTheEvents(api) { const unboundKey = api.symbol('unbound'); for (let i = 0; i < eventNames.length; i++) { const property = eventNames[i]; const onproperty = 'on' + property; self.addEventListener(property, function (event) { let elt = event.target, bound, source; if (elt) { source = elt.constructor['name'] + '.' + onproperty; } else { source = 'unknown.' + onproperty; } while (elt) { if (elt[onproperty] && !elt[onproperty][unboundKey]) { bound = api.wrapWithCurrentZone(elt[onproperty], source); bound[unboundKey] = elt[onproperty]; elt[onproperty] = bound; } elt = elt.parentElement; } }, true); } } function registerElementPatch(_global, api) { const { isBrowser, isMix } = api.getGlobalObjects(); if ((!isBrowser && !isMix) || !('registerElement' in _global.document)) { return; } const callbacks = ['createdCallback', 'attachedCallback', 'detachedCallback', 'attributeChangedCallback']; api.patchCallbacks(api, document, 'Document', 'registerElement', callbacks); } /** * @fileoverview * @suppress {missingRequire} */ (function (_global) { const symbolPrefix = _global['__Zone_symbol_prefix'] || '__zone_symbol__'; function __symbol__(name) { return symbolPrefix + name; } _global[__symbol__('legacyPatch')] = function () { const Zone = _global['Zone']; Zone.__load_patch('defineProperty', (global, Zone, api) => { api._redefineProperty = _redefineProperty; propertyPatch(); }); Zone.__load_patch('registerElement', (global, Zone, api) => { registerElementPatch(global, api); }); Zone.__load_patch('EventTargetLegacy', (global, Zone, api) => { eventTargetLegacyPatch(global, api); propertyDescriptorLegacyPatch(api, global); }); }; })(typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {});