all files / src/ ve.freeze.js

95.45% Statements 21/22
93.75% Branches 15/16
100% Functions 4/4
95.45% Lines 21/22
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66                                                    528×   528× 22× 22×   528× 2608× 1251× 1251×             506×   506×         528× 527×     527×   528×      
/*!
 * VisualEditor Object freeze utilities.
 *
 * @copyright 2011-2019 VisualEditor Team and others; see http://ve.mit-license.org
 */
 
/* global Set */
 
( function () {
	var deepFreeze, freezeProxyHandler;
	freezeProxyHandler = {
		set: function ( obj, name ) {
			throw new Error( 'Object is frozen, can\'t set property: ' + name );
		},
		deleteProperty: function ( obj, name ) {
			throw new Error( 'Object is frozen, can\'t delete property: ' + name );
		}
	};
 
	Iif ( !window.Proxy || !window.Set ) {
		return;
	}
	/**
	 * Deep freeze an object, making it immutable
	 *
	 * Original object properties are overwritten with frozen versions.
	 *
	 * @param {Object} object Object to freeze
	 * @param {boolean} [onlyProperties] Only freeze properties (or array items)
	 * @param {Set} [seen] Set of already-seen objects (for internal, recursive use)
	 * @return {Object} Immutable deep copy of the original object
	 */
	ve.deepFreeze = deepFreeze = function ( object, onlyProperties, seen ) {
		var name, value;
 
		if ( !seen ) {
			seen = new Set();
			seen.add( object );
		}
		for ( name in object ) {
			if ( Object.prototype.hasOwnProperty.call( object, name ) ) {
				value = object[ name ];
				if (
					// Truth check so we don't try to freeze null
					value &&
					typeof value === 'object' &&
					!seen.has( value ) &&
					!Object.isFrozen( value )
				) {
					seen.add( value );
					// Recurse. Use local name (tests may alias ve.deepFreeze)
					object[ name ] = deepFreeze( value, false, seen );
				}
			}
		}
 
		if ( !onlyProperties ) {
			object = new window.Proxy( object, freezeProxyHandler );
			// Object#freeze isn't really necessary after proxying,
			// but use it so we can detect frozen objects with Object.isFrozen.
			Object.freeze( object );
		}
		return object;
	};
}() );