import { DOM } from 'aurelia-pal' ; import { subscriberCollection , EventSubscriber } from 'aurelia-binding' ; import { IMdcSelectElement } from './mdc-select' ; interface ISubscriberCollection { addSubscriber ( context , callable ) : boolean ; removeSubscriber ( context , callable ) : boolean ; callSubscribers ( newValue , oldValue ) : void ; hasSubscribers ( ) : boolean ; hasSubscriber ( context , callable ) : boolean ; } hidden @ subscriberCollection ( ) export class MdcSelectValueObserver { constructor ( element , private handler ) { this . element = element as IMdcSelectElement ; } value : unknown ; oldValue : unknown ; element : IMdcSelectElement ; domObserver : MutationObserver | null ; optionsWereSet : boolean ; setElementValue ( skipNotify = false ) { if ( this . optionsWereSet ) { this . element . au . controller . viewModel . setValue ( this . value , skipNotify ) ; } } getValue ( ) { return this . value ; } setValue ( newValue ) { if ( this . value === newValue ) { return ; } this . oldValue = this . value ; this . value = newValue ; this . setElementValue ( ) ; this . notify ( ) ; } synchronizeValue ( ) { const value = this . element . value ; if ( value !== this . value ) { this . oldValue = this . value ; this . value = value ; this . notify ( ) ; } } notify ( ) { const oldValue = this . oldValue ; const newValue = this . value ; ( this as unknown as ISubscriberCollection ) . callSubscribers ( newValue , oldValue ) ; } handleEvent ( ) { this . synchronizeValue ( ) ; } subscribe ( context , callable ) { if ( ! ( this as unknown as ISubscriberCollection ) . hasSubscribers ( ) ) { this . handler . subscribe ( this . element , this ) ; } ( this as unknown as ISubscriberCollection ) . addSubscriber ( context , callable ) ; } unsubscribe ( context , callable ) { if ( ( this as unknown as ISubscriberCollection ) . removeSubscriber ( context , callable ) && ! ( this as unknown as ISubscriberCollection ) . hasSubscribers ( ) ) { this . handler . dispose ( ) ; } } bind ( ) { const menu = this . element . querySelector ( '.mdc-menu' ) ! ; this . optionsWereSet = ! ! menu . querySelector ( 'mdc-list-item' ) ; this . domObserver = DOM . createMutationObserver ( ( records ) => { if ( records . find ( x => x . type === 'childList' && ( Array . from ( x . addedNodes ) . find ( y => ( y as HTMLElement ) . tagName === 'MDC-LIST-ITEM' ) || Array . from ( x . removedNodes ) . find ( y => ( y as HTMLElement ) . tagName === 'MDC-LIST-ITEM' ) ) ) ) { if ( ! this . optionsWereSet ) { this . optionsWereSet = true ; this . setElementValue ( true ) ; } this . synchronizeValue ( ) ; } } ) ; this . domObserver . observe ( menu , { childList : true , subtree : true , characterData : true } ) ; } unbind ( ) { this . optionsWereSet = false ; this . domObserver ?. disconnect ( ) ; this . domObserver = null ; } }