
committed by
Kara Erickson

parent
7b3bcc23af
commit
5eb7426216
111
packages/zone.js/lib/browser/define-property.ts
Normal file
111
packages/zone.js/lib/browser/define-property.ts
Normal file
@ -0,0 +1,111 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
const zoneSymbol = Zone.__symbol__;
|
||||
const _defineProperty = (Object as any)[zoneSymbol('defineProperty')] = Object.defineProperty;
|
||||
const _getOwnPropertyDescriptor = (Object as any)[zoneSymbol('getOwnPropertyDescriptor')] =
|
||||
Object.getOwnPropertyDescriptor;
|
||||
const _create = Object.create;
|
||||
const unconfigurablesKey = zoneSymbol('unconfigurables');
|
||||
|
||||
export function propertyPatch() {
|
||||
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) {
|
||||
Object.keys(props).forEach(function(prop) { Object.defineProperty(obj, prop, props[prop]); });
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user