(obj: any, prop: string, prototype?: any)
| 195 | }; |
| 196 | |
| 197 | export function patchProperty(obj: any, prop: string, prototype?: any) { |
| 198 | let desc = ObjectGetOwnPropertyDescriptor(obj, prop); |
| 199 | if (!desc && prototype) { |
| 200 | // when patch window object, use prototype to check prop exist or not |
| 201 | const prototypeDesc = ObjectGetOwnPropertyDescriptor(prototype, prop); |
| 202 | if (prototypeDesc) { |
| 203 | desc = {enumerable: true, configurable: true}; |
| 204 | } |
| 205 | } |
| 206 | // if the descriptor not exists or is not configurable |
| 207 | // just return |
| 208 | if (!desc || !desc.configurable) { |
| 209 | return; |
| 210 | } |
| 211 | |
| 212 | const onPropPatchedSymbol = zoneSymbol('on' + prop + 'patched'); |
| 213 | if (obj.hasOwnProperty(onPropPatchedSymbol) && obj[onPropPatchedSymbol]) { |
| 214 | return; |
| 215 | } |
| 216 | |
| 217 | // A property descriptor cannot have getter/setter and be writable |
| 218 | // deleting the writable and value properties avoids this error: |
| 219 | // |
| 220 | // TypeError: property descriptors must not specify a value or be writable when a |
| 221 | // getter or setter has been specified |
| 222 | delete desc.writable; |
| 223 | delete desc.value; |
| 224 | const originalDescGet = desc.get; |
| 225 | const originalDescSet = desc.set; |
| 226 | |
| 227 | // slice(2) cuz 'onclick' -> 'click', etc |
| 228 | const eventName = prop.slice(2); |
| 229 | |
| 230 | let eventNameSymbol = zoneSymbolEventNames[eventName]; |
| 231 | if (!eventNameSymbol) { |
| 232 | eventNameSymbol = zoneSymbolEventNames[eventName] = zoneSymbol('ON_PROPERTY' + eventName); |
| 233 | } |
| 234 | |
| 235 | desc.set = function (this: EventSource, newValue) { |
| 236 | // In some versions of Windows, the `this` context may be undefined |
| 237 | // in on-property callbacks. |
| 238 | // To handle this edge case, we check if `this` is falsy and |
| 239 | // fallback to `_global` if needed. |
| 240 | let target = this; |
| 241 | if (!target && obj === _global) { |
| 242 | target = _global; |
| 243 | } |
| 244 | if (!target) { |
| 245 | return; |
| 246 | } |
| 247 | |
| 248 | const previousValue = (target as any)[eventNameSymbol]; |
| 249 | if (typeof previousValue === 'function') { |
| 250 | target.removeEventListener(eventName, wrapFn); |
| 251 | } |
| 252 | |
| 253 | // https://github.com/angular/zone.js/issues/978 |
| 254 | // If an inline handler (like `onload`) was defined before zone.js was loaded, |
no test coverage detected
searching dependent graphs…