Repository: NativeScript/NativeScript
File: packages/core/data/observable/index.ts (TypeScript)

Code before:

const eventNamesRegex = /\s*,\s*/;

/**
 * Observable is used when you want to be notified when a change occurs. Use on/off methods to add/remove listener.
 * Please note that should you be using the `new Observable({})` constructor, it is **obsolete** since v3.0,
 * and you have to migrate to the "data/observable" `fromObject({})` or the `fromObjectRecursive({})` functions.
 */
export class Observable {
	/**
	 * String value used when hooking to propertyChange event.
	 */
	public static propertyChangeEvent = 'propertyChange';

	/**
	 * This is a simple constant to allow renderers to confirm, at runtime, what
	 * the call signatures of Observable.addEventListener() and
	 * Observable.prototype.addEventListener() are. This may help us one day
	 * migrate to an EventTarget-conformant signature (i.e. dropping `thisArg`).
	 *
	 * Full context of what each version number means would require referring to
	 * the source. It's intended that any time a change is made to the call
	 * signature, we increment the number. Once we've completed the migration, we
	 * can remove it altogether.
	 */
	public static readonly addEventListenerSchemaVersion = 1;

	/**
	 * Alternative to `instanceof ViewBase`.
	 * @private
	 */
	public _isViewBase: boolean;

	private readonly _observers: { [eventName: string]: Array<ListenerEntry> } = {};

	/**
	 * Gets the value of the specified property.
	 */
	public get(name: string): any {
		return this[name];
	}

	/**
	 * Updates the specified property with the provided value.
	 */
	public set(name: string, value: any): void {
		// TODO: Parameter validation
		const oldValue = this[name];
		if (this[name] === value) {
			return;
		}

Review comment (security):
I’m having second thoughts about this property. Not sure renderer authors will necessarily find it useful compared to just pinning to a minimum version range of Core.

I’ll remove it when I get a chance.

Code after:

const eventNamesRegex = /\s*,\s*/;

/**
 * Observable is used when you want to be notified when a change occurs. Use on/off methods to add/remove listener.
 * Please note that should you be using the `new Observable({})` constructor, it is **obsolete** since v3.0,
 * and you have to migrate to the "data/observable" `fromObject({})` or the `fromObjectRecursive({})` functions.
 */
export class Observable {
	/**
	 * String value used when hooking to propertyChange event.
	 */
	public static propertyChangeEvent = 'propertyChange';

	/**
	 * Alternative to `instanceof ViewBase`.
	 * @private
	 */
	public _isViewBase: boolean;

	private readonly _observers: { [eventName: string]: Array<ListenerEntry> } = {};

	/**
	 * Gets the value of the specified property.
	 */
	public get(name: string): any {
		return this[name];
	}

	/**
	 * Updates the specified property with the provided value.
	 */
	public set(name: string, value: any): void {
		// TODO: Parameter validation
		const oldValue = this[name];
		if (this[name] === value) {
			return;
		}

		const newValue = WrappedValue.unwrap(value);
		this[name] = newValue;
		this.notifyPropertyChange(name, newValue, oldValue);
	}

	/**
	 * Updates the specified property with the provided value and raises a property change event and a specific change event based on the property name.
	 */
	public setProperty(name: string, value: any): void {
		const oldValue = this[name];
		if (this[name] === value) {
			return;