/*! * Copyright (c) Microsoft. All rights reserved. * Licensed under the MIT license. See LICENSE file in the project. */ import { EventEmitter } from './events' export type PropertyChangeHandler = (newValue: T) => void export type PropertyChangeValidator = (newValue: T) => boolean export type AreEqualFn = (a: T, b: T) => boolean export const identity = (a: T, b: T): boolean => a === b export interface PropertyContainerEvents { /** * Event that is raised when the property is changed * @param value The new value */ change(value: T | undefined): void } /** * @internal * * A class for managing a property that emits an event when it changes */ export class PropertyContainer extends EventEmitter< PropertyContainerEvents > { private isValid: PropertyChangeValidator = () => true private areEqual: AreEqualFn /** * Constructor * @param _value The current value * @param areEqual An equality function */ public constructor(private _value: T, areEqual: AreEqualFn = identity) { super() this.areEqual = areEqual } /** * Sets the validator which validates whether or not a value is a valid value for this property container * @param isValid The validator */ public checkValidity(isValid: PropertyChangeValidator): void { this.isValid = isValid } /** * Gets the value contained in the container */ public get value(): T { return this._value } /** * Sets the value in the container */ public set value(newValue: T) { if (this.isValid(newValue) && !this.areEqual(newValue, this._value)) { this._value = newValue this.emit('change', newValue) } } }