/**
 * observable模块的工具方法，用于创建可观察的数据，数据绑定等
 */ namespace drunk . observable { import util = drunk . util ; param data export function create < T > ( data ) { let isObject = util . isPlainObjectOrObservableObject ( data ) ; if ( ! isObject && ! Array . isArray ( data ) ) { return ; } let ob ; if ( typeof data . __observer__ === 'undefined' ) { ob = new Observer ( ) ; Object . defineProperties ( data , { __observer__ : { value : ob , writable : true , configurable : true } } ) ; if ( isObject ) { data . __proto__ = ObservableObjectPrototype ; Object . keys ( data ) . forEach ( ( property ) => { observe ( data , property , data [ property ] ) ; } ) ; } else { data . __proto__ = ObservableArrayPrototype ; data . forEach ( ( item ) => { create ( item ) ; } ) ; } } else { ob = data . __observer__ ; } return ob ; } param observer param property param value param data export var onPropertyAccessing ; param data param property export function observe ( target , property , value ) { let descriptor = Object . getOwnPropertyDescriptor ( target , property ) ; if ( descriptor && typeof descriptor . get === 'function' && descriptor . get === descriptor . set ) { return ; } let targetObserver = create ( target ) ; let valueObserver = create ( value ) ; Object . defineProperty ( target , property , { enumerable : true , configurable : true , get : propertyGetterSetter , set : propertyGetterSetter } ) ; if ( valueObserver ) { valueObserver . addPropertyChangedCallback ( propertyChanged ) ; } function propertyGetterSetter ( ) { if ( arguments . length === 0 ) { if ( onPropertyAccessing ) { onPropertyAccessing ( targetObserver , property , value , target ) ; } return value ; } let newValue = arguments [ 0 ] ; if ( ! util . isObjectOrNotEqual ( newValue , value ) ) { return ; } if ( valueObserver ) { valueObserver . removePropertyChangedCallback ( propertyChanged ) ; } value = newValue ; valueObserver = create ( newValue ) ; if ( valueObserver ) { valueObserver . addPropertyChangedCallback ( propertyChanged ) ; } propertyChanged ( ) ; } function propertyChanged ( ) { targetObserver . $emit ( property ) ; } } param data param property export function notify < T > ( data ) { let observer = data . __observer__ ; if ( observer ) { observer . notify ( ) ; } } }