import * as ko from "knockout" ; import { SurveyHelper , ObjType } from "./surveyHelper" ; import { editorLocalization } from "./editorLocalization" ; import * as Survey from "survey-knockout" ; export class SurveyObjectItem { public value : Survey . Base ; public text : any ; public level : number = 0 ; } export class SurveyObjects { public static intend : string = "." ; surveyValue : Survey . Survey ; public getItemTextCallback : ( obj : Survey . Base , text : string ) => string ; constructor ( public koObjects , public koSelected , private getObjectDisplayName = null ) { } public get survey ( ) : Survey . Survey { return this . surveyValue ; } public set survey ( value ) { if ( this . survey == value ) return ; this . surveyValue = value ; this . rebuild ( ) ; } public hasObject ( obj ) { return this . getItemIndex ( obj ) > - 1 ; } public addPage ( page ) { this . addElement ( page , null ) ; } public addElement ( element , parent ) { var parentIndex = parent != null ? this . getItemIndex ( parent ) : 0 ; if ( parentIndex < 0 ) return ; var elements = parent != null ? this . getElements ( parent ) : this . survey . pages ; var elementIndex = elements . indexOf ( element ) ; var newIndex = elementIndex + 1 + parentIndex ; if ( elementIndex > 0 ) { var prevElement = elements [ elementIndex - 1 ] ; newIndex = this . getItemIndex ( prevElement ) + this . getAllElementCount ( prevElement ) + 1 ; } var item = this . createItem ( element , this . koObjects ( ) [ parentIndex ] ) ; this . addItem ( item , newIndex ) ; var objs = [ ] ; this . buildElements ( objs , this . getElements ( element ) , item ) ; for ( var i = 0 ; i < objs . length ; i ++ ) { this . koObjects . splice ( newIndex + 1 + i , 0 , objs [ i ] ) ; } if ( SurveyHelper . canSelectObj ( element ) ) { this . koSelected ( item ) ; } } public selectObject ( obj ) { if ( ! ! obj && ! SurveyHelper . canSelectObj ( obj ) ) return ; if ( obj === null ) { this . koSelected ( null ) ; return ; } var objs = this . koObjects ( ) ; for ( var i = 0 ; i < objs . length ; i ++ ) { if ( objs [ i ] . value == obj ) { this . koSelected ( objs [ i ] ) ; return ; } } } public getSelectedObjectPage ( obj = null ) { if ( ! this . survey ) return null ; if ( ! obj ) { if ( ! this . koSelected ( ) ) return ; obj = this . koSelected ( ) . value ; } var objs = this . koObjects ( ) ; var index = this . getItemIndex ( obj ) ; while ( index > 0 ) { var item = objs [ index ] ; if ( item . level == 1 ) return item . value ; index -- ; } return null ; } public removeObject ( obj ) { var index = this . getItemIndex ( obj ) ; if ( index < 0 ) return ; var countToRemove = 1 + this . getAllElementCount ( obj ) ; this . koObjects . splice ( index , countToRemove ) ; } public nameChanged ( obj ) { var index = this . getItemIndex ( obj ) ; if ( index < 0 ) return ; var item = this . koObjects ( ) [ index ] ; item . text ( this . getText ( item ) ) ; } public selectNextQuestion ( isUp ) { var question = this . getSelectedQuestion ( ) ; var itemIndex = this . getItemIndex ( question ) ; if ( itemIndex < 0 ) return question ; var objs = this . koObjects ( ) ; var newItemIndex = itemIndex + ( isUp ? - 1 : 1 ) ; if ( newItemIndex < objs . length && SurveyHelper . getObjectType ( objs [ newItemIndex ] . value ) == ObjType . Question ) { itemIndex = newItemIndex ; } else { newItemIndex = itemIndex ; while ( newItemIndex < objs . length && SurveyHelper . getObjectType ( objs [ newItemIndex ] . value ) == ObjType . Question ) { itemIndex = newItemIndex ; newItemIndex += isUp ? 1 : - 1 ; } } this . koSelected ( objs [ itemIndex ] ) ; } private getAllElementCount ( element ) { var elements = this . getElements ( element ) ; var res = 0 ; for ( var i = 0 ; i < elements . length ; i ++ ) { res += 1 + this . getAllElementCount ( elements [ i ] ) ; } return res ; } private getSelectedQuestion ( ) { if ( ! this . koSelected ( ) ) return null ; var obj = this . koSelected ( ) . value ; if ( ! obj ) return null ; return SurveyHelper . getObjectType ( obj ) == ObjType . Question ? < Survey . Question > obj : null ; } private addItem ( item , index ) { if ( index > this . koObjects ( ) . length ) { this . koObjects . push ( item ) ; } else { this . koObjects . splice ( index , 0 , item ) ; } } private rebuild ( ) { var objs = [ ] ; if ( this . survey == null ) { this . koObjects ( objs ) ; this . selectObject ( null ) ; return ; } var root = this . createItem ( this . survey , null ) ; objs . push ( root ) ; for ( var i = 0 ; i < this . survey . pages . length ; i ++ ) { var page = < Survey . Page > this . survey . pages [ i ] ; var pageItem = this . createItem ( page , root ) ; objs . push ( pageItem ) ; this . buildElements ( objs , this . getElements ( page ) , pageItem ) ; } this . koObjects ( objs ) ; this . selectObject ( this . survey ) ; } private getElements ( element ) { return SurveyHelper . getElements ( element ) ; } private buildElements ( objs , elements , parentItem ) { for ( var i = 0 ; i < elements . length ; i ++ ) { var el = elements [ i ] ; var item = this . createItem ( < Survey . Base > el , parentItem ) ; objs . push ( item ) ; this . buildElements ( objs , this . getElements ( el ) , item ) ; } } private createItem ( value , parent ) { var item = new SurveyObjectItem ( ) ; item . value = value ; item . level = parent != null ? parent . level + 1 : 0 ; item . text = ko . observable ( this . getText ( item ) ) ; return item ; } private getItemIndex ( value ) { if ( ! value ) return - 1 ; if ( value [ "selectedElementInDesign" ] ) value = value [ "selectedElementInDesign" ] ; var objs = this . koObjects ( ) ; for ( var i = 0 ; i < objs . length ; i ++ ) { if ( objs [ i ] . value == value ) return i ; } return - 1 ; } private getText ( item ) { if ( item . level == 0 ) return editorLocalization . getString ( "ed.survey" ) ; var intend = SurveyObjects . intend ; for ( var i = 1 ; i < item . level ; i ++ ) { intend += SurveyObjects . intend ; } var text = ! ! this . getObjectDisplayName ? this . getObjectDisplayName ( item . value , "property-grid" ) : SurveyHelper . getObjectName ( item . value , false ) ; if ( this . getItemTextCallback ) { text = this . getItemTextCallback ( item . value , text ) ; } return intend + text ; } }