| 
									
										
										
										
											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
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  |  * This is necessary for Chrome and Chrome mobile, to enable | 
					
						
							|  |  |  |  * things like redefining `createdCallback` on an element. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-06 09:54:54 +09:00
										 |  |  | let zoneSymbol: any; | 
					
						
							|  |  |  | let _defineProperty: any; | 
					
						
							|  |  |  | let _getOwnPropertyDescriptor: any; | 
					
						
							|  |  |  | let _create: any; | 
					
						
							|  |  |  | let unconfigurablesKey: any; | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | export function propertyPatch() { | 
					
						
							| 
									
										
										
										
											2019-08-06 09:54:54 +09:00
										 |  |  |   zoneSymbol = Zone.__symbol__; | 
					
						
							|  |  |  |   _defineProperty = (Object as any)[zoneSymbol('defineProperty')] = Object.defineProperty; | 
					
						
							|  |  |  |   _getOwnPropertyDescriptor = (Object as any)[zoneSymbol('getOwnPropertyDescriptor')] = | 
					
						
							|  |  |  |       Object.getOwnPropertyDescriptor; | 
					
						
							|  |  |  |   _create = Object.create; | 
					
						
							|  |  |  |   unconfigurablesKey = zoneSymbol('unconfigurables'); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |   Object.defineProperty = function(obj: any, prop: string, desc: any) { | 
					
						
							|  |  |  |     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) { | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |     Object.keys(props).forEach(function(prop) { | 
					
						
							|  |  |  |       Object.defineProperty(obj, prop, props[prop]); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |     return obj; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Object.create = <any>function(obj: any, proto: any) { | 
					
						
							|  |  |  |     if (typeof proto === 'object' && !Object.isFrozen(proto)) { | 
					
						
							|  |  |  |       Object.keys(proto).forEach(function(prop) { | 
					
						
							|  |  |  |         proto[prop] = rewriteDescriptor(obj, prop, proto[prop]); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return _create(obj, proto); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Object.getOwnPropertyDescriptor = function(obj, prop) { | 
					
						
							|  |  |  |     const desc = _getOwnPropertyDescriptor(obj, prop); | 
					
						
							|  |  |  |     if (desc && isUnconfigurable(obj, prop)) { | 
					
						
							|  |  |  |       desc.configurable = false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return desc; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export function _redefineProperty(obj: any, prop: string, desc: any) { | 
					
						
							|  |  |  |   const originalConfigurableFlag = desc.configurable; | 
					
						
							|  |  |  |   desc = rewriteDescriptor(obj, prop, desc); | 
					
						
							|  |  |  |   return _tryDefineProperty(obj, prop, desc, originalConfigurableFlag); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function isUnconfigurable(obj: any, prop: any) { | 
					
						
							|  |  |  |   return obj && obj[unconfigurablesKey] && obj[unconfigurablesKey][prop]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function rewriteDescriptor(obj: any, prop: string, desc: any) { | 
					
						
							|  |  |  |   // 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: any, prop: string, desc: any, originalConfigurableFlag: any) { | 
					
						
							|  |  |  |   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) { | 
					
						
							| 
									
										
										
										
											2020-09-01 08:26:11 +09:00
										 |  |  |         let swallowError = false; | 
					
						
							| 
									
										
										
										
											2020-09-01 08:26:55 +09:00
										 |  |  |         if (prop === 'createdCallback' || prop === 'attachedCallback' || | 
					
						
							|  |  |  |             prop === 'detachedCallback' || prop === 'attributeChangedCallback') { | 
					
						
							| 
									
										
										
										
											2020-09-01 08:26:11 +09:00
										 |  |  |           // We only swallow the error in registerElement patch
 | 
					
						
							| 
									
										
										
										
											2020-09-01 08:26:55 +09:00
										 |  |  |           // this is the work around since some applications
 | 
					
						
							|  |  |  |           // fail if we throw the error
 | 
					
						
							| 
									
										
										
										
											2020-09-01 08:26:11 +09:00
										 |  |  |           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.
 | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |         let descJson: string|null = 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; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |