import { CustomPropertyHandler , PropertyResolveResult } from "../providers/property-handler-provider" ; import * as parseXml from '../parser/types' ; import { WidgetModel , AttributeModel , PropertyModel } from '../models/models' ; import { ConfigHandlerAndPropertyModel } from '../models/config' ; import { PipeValueResolver } from "../resolvers/pipe-value-resolver" ; import { ValueTransformersProvider } from "../providers/value-transformers-provider" ; import { PropertyResolver } from "../resolvers/property-resolver" ; export class WrapperPropertyHandler extends CustomPropertyHandler { protected getProperty ( handler ) { const property = this . properties . filter ( a => a . handler === handler ) [ 0 ] ; if ( property ) { return property ; } return { handler : '' , targetProperty : '' } ; } constructor ( protected propertyResolver , protected properties , protected targetWidgetType , protected defaults ? , priority = 100 ) { super ( ) ; this . priority = priority ; } getRelatedProperties ( element , handlerProperty , widget ) { return this . properties . map ( a => a . handler ) ; } canResolve ( element , handlerProperty , widget ) { return true ; } resolve ( element , attr , widget ) { const property = this . getProperty ( attr . name ) ; attr . value = property . value !== null && property . value !== undefined ? property . value : attr . value ; const value = property . targetProperty ? ValueTransformersProvider . transform ( attr . value , property . targetProperty , this . targetWidgetType ) : attr . value ; let grandparentWidget = null as any ; let lastCustomParent = null as any ; if ( widget . isCustom ) { const getFirstNonCustomWidget = ( w ) : { customParent : WidgetModel ; nonCustomChild : WidgetModel ; } => { if ( w . wrappedWidgets && w . wrappedWidgets [ 0 ] ) { if ( w . isCustom && ! w . wrappedWidgets [ 0 ] . isCustom ) { return { customParent : w , nonCustomChild : w . wrappedWidgets [ 0 ] } ; } else { return getFirstNonCustomWidget ( w . wrappedWidgets [ 0 ] ) ; } } return null as any ; } ; grandparentWidget = widget ; const result = getFirstNonCustomWidget ( widget ) ; widget = result . nonCustomChild ; lastCustomParent = result . customParent ; } const onWrapped = [ ] ; const creationResult = this . createWrapperWidget ( widget , property . targetProperty , value , onWrapped ) ; let wrapperWidget = creationResult . wrapperWidget ; const relatedProperties = this . createRelatedProperties ( element . attributes , property . targetProperty ) ; creationResult . wrapperWidget . properties . push ( ... relatedProperties ) ; const defaultValues = this . createPropertiesDefaultValues ( ) ; creationResult . wrapperWidget . properties . push ( ... defaultValues ) ; for ( const prop of relatedProperties ) { const resolveResult = this . propertyResolver . pipeValueResolver . resolve ( element , prop . name , prop . value as any , wrapperWidget , true ) ; wrapperWidget = resolveResult . wrapperWidget || wrapperWidget ; prop . value = resolveResult . value ; } if ( typeof value === 'string' ) { const resolveResult = this . propertyResolver . pipeValueResolver . resolve ( element , attr . name , value , wrapperWidget , true ) ; if ( creationResult . propertyToUpdateAfterBinding ) { creationResult . propertyToUpdateAfterBinding . value = resolveResult . value ; } if ( resolveResult . wrapperWidget ) { wrapperWidget = resolveResult . wrapperWidget || wrapperWidget ; onWrapped . forEach ( a => a && a ( resolveResult . wrapperWidget as any ) ) ; } } if ( grandparentWidget ) { lastCustomParent . wrappedWidgets = [ wrapperWidget ] ; wrapperWidget = grandparentWidget ; } return { extraData : null , wrapperWidget , value : attr . value , handled : true } ; } protected createRelatedProperties ( attributes , targetProperty ) { const related = this . properties . filter ( prop => prop . targetProperty !== targetProperty && prop . handler in attributes ) . map ( prop => { const value = ValueTransformersProvider . transform ( attributes [ prop . handler ] , prop . handler , this . targetWidgetType ) ; return { value , name : prop . targetProperty , dataType : 'object' } as PropertyModel ; } ) ; return related ; } protected createWrapperWidget ( widget , targetProperty , value , onWrapped ) { const propertyName = this . propertyResolver . isUnNamedParameter ( targetProperty , this . targetWidgetType ) ? '' : targetProperty ; const wrapperWidget = { controllers : [ ] , vars : [ ] , formControls : [ ] , properties : [ { dataType : 'object' , name : propertyName , value : value } , { dataType : 'widget' , name : 'child' , value : widget } ] , type : this . targetWidgetType , wrappedWidgets : [ widget ] , onResolved : [ ] } ; return { wrapperWidget , propertyToUpdateAfterBinding : wrapperWidget . properties [ 0 ] } ; } protected createPropertiesDefaultValues ( ) { const defaults = this . defaults || { } ; return Object . keys ( defaults ) . map ( k => { return { name : k , value : defaults [ k ] , dataType : 'object' } as PropertyModel ; } ) ; } }