import { Common } from '../common' ; import { Constants } from '../constants' ; import { Capivara } from '../index' ; import { CPAttr } from './directive/cp-attr' ; import { CPBlur } from './directive/cp-blur' ; import { CPChange } from './directive/cp-change' ; import { CPClass } from './directive/cp-class' ; import { CPClick } from './directive/cp-click' ; import { CPDisabled } from './directive/cp-disabled' ; import { CPElse } from './directive/cp-else' ; import { CPElseIf } from './directive/cp-else-if' ; import { CPFocus } from './directive/cp-focus' ; import { CPHide } from './directive/cp-hide' ; import { CPIf } from './directive/cp-if' ; import { CPInit } from './directive/cp-init' ; import { CPKey } from './directive/cp-key' ; import { CPModel } from './directive/cp-model' ; import { CPMouse } from './directive/cp-mouse' ; import { CPRepeat } from './directive/cp-repeat' ; import { CPShow } from './directive/cp-show' ; import { CPStyle } from './directive/cp-style' ; export class MapDom { /**
     * Elemento principal que está aplicado o escopo
     */ private readonly element : HTMLElement ; private directives = { /**
         * Mapa de atributos com os elementos que os observam.
         */ cpModelsElements : { } , /**
         * Array com os cp-repeat
         */ cpIfs : [ ] , cpModels : [ ] , repeats : [ ] , cpShows : [ ] , cpElses : [ ] , cpElseIfs : [ ] , cpStyles : [ ] , cpClasses : [ ] , cpClicks : [ ] , cpInits : [ ] , cpKeys : [ ] , cpAttrs : [ ] , cpDisables : [ ] , cpFocus : [ ] , cpHide : [ ] , cpBlur : [ ] , cpMouse : [ ] , cpChange : [ ] , } ; private readonly regexInterpolation ; description private renderedView : boolean ; constructor ( _element ) { this . element = _element ; this . regexInterpolation = new RegExp ( /({{).*?(}})/g ) ; this . setRenderedView ( false ) ; if ( this . element ) { this . $addScope ( ) ; } } method public $addScope ( ) { this . createDirectives ( this . element ) ; const recursiveBind = ( element ) => { Array . from ( element . children ) . forEach ( ( child ) => { child [ Constants . SCOPE_ATTRIBUTE_NAME ] = Common . getScope ( this . element ) ; this . createDirectives ( child ) ; if ( child . children ) { recursiveBind ( child ) ; } } ) ; } ; recursiveBind ( this . element ) ; this . $directivesInit ( ) ; } private setRenderedView ( value ) { this . renderedView = value ; } public $directivesInit ( ) { Common . getScope ( this . element ) . $on ( '$onInit' , ( ) => { Object . keys ( this . directives ) . forEach ( ( key ) => { const directives = this . directives [ key ] ; if ( Array . isArray ( directives ) ) { directives . forEach ( ( directive ) => directive . create ( ) ) ; } } ) ; this . $viewInit ( ) ; } ) ; } private $viewInit ( ) { this . setRenderedView ( true ) ; if ( this . element [ '$instance' ] ) { const ctrl = Common . getScope ( this . element ) . scope [ this . element [ '$instance' ] . config . controllerAs ] ; if ( ctrl && ctrl [ '$onViewInit' ] ) { ctrl [ '$onViewInit' ] ( ) ; } } } method param child public createDirectives ( child ) { if ( child . hasAttribute ( Constants . MODEL_ATTRIBUTE_NAME ) ) { this . createCPModel ( child ) ; } if ( child . hasAttribute ( Constants . IF_ATTRIBUTE_NAME ) ) { this . createCPIf ( child ) ; } if ( child . hasAttribute ( Constants . CLICK_ATTRIBUTE_NAME ) || child . hasAttribute ( Constants . DBLCLICK_ATTRIBUTE_NAME ) ) { this . createCPClick ( child ) ; } if ( child . hasAttribute ( Constants . REPEAT_ATTRIBUTE_NAME ) ) { this . createCPRepeat ( child ) ; } if ( child . hasAttribute ( Constants . SHOW_ATTRIBUTE_NAME ) ) { this . createCPShow ( child ) ; } if ( child . hasAttribute ( Constants . ELSE_ATTRIBUTE_NAME ) ) { this . createCPElse ( child ) ; } if ( child . hasAttribute ( Constants . ELSE_IF_ATTRIBUTE_NAME ) ) { this . createCPElseIf ( child ) ; } if ( child . hasAttribute ( Constants . INIT_ATTRIBUTE_NAME ) ) { this . createCPInit ( child ) ; } if ( child . hasAttribute ( Constants . STYLE_ATTRIBUTE_NAME ) ) { this . createCPStyle ( child ) ; } if ( child . hasAttribute ( Constants . CLASS_ATTRIBUTE_NAME ) ) { this . createCPClass ( child ) ; } if ( child . hasAttributeStartingWith ( Constants . KEY_ATTRIBUTE_NAME ) ) { this . createCPKey ( child ) ; } if ( child . hasAttributeStartingWith ( Constants . ATTR_ATTRIBUTE_NAME ) ) { this . createCPAttr ( child ) ; } if ( child . hasAttribute ( Constants . DISABLE_ATTRIBUTE_NAME ) ) { this . createCPDisabled ( child ) ; } if ( child . hasAttribute ( Constants . FOCUS_ATTRIBUTE_NAME ) ) { this . createCPFocus ( child ) ; } if ( child . hasAttribute ( Constants . HIDE_ATTRIBUTE_NAME ) ) { this . createCPHide ( child ) ; } if ( child . hasAttribute ( Constants . BLUR_ATTRIBUTE_NAME ) ) { this . createCPBlur ( child ) ; } if ( child . hasAttributeStartingWith ( Constants . MOUSE_ATTRIBUTE_NAME ) ) { this . createCPmouse ( child ) ; } if ( child . hasAttribute ( Constants . CHANGE_ATTRIBUTE_NAME ) ) { this . createCPChange ( child ) ; } } public reloadElementChildes ( element , initialScope ) { if ( element . children ) { Array . from ( element . children ) . forEach ( ( child ) => { const childScope = Common . getScope ( child ) ; if ( childScope && childScope . mapDom && childScope . id !== initialScope . id ) { childScope . mapDom . reloadDirectives ( ) ; } this . reloadElementChildes ( child , initialScope ) ; } ) ; } } public reloadDirectives ( ) { Object . keys ( this . directives . cpModelsElements ) . forEach ( ( key ) => this . directives . cpModelsElements [ key ] . forEach ( ( bind ) => bind . applyModelInValue ( ) ) ) ; this . directives . repeats . forEach ( ( repeat ) => repeat . applyLoop ( ) ) ; this . directives . cpShows . forEach ( ( cpShow ) => cpShow . init ( ) ) ; this . directives . cpIfs . forEach ( ( cpIf ) => cpIf . init ( ) ) ; this . directives . cpElseIfs . forEach ( ( cpElseIf ) => cpElseIf . init ( ) ) ; this . directives . cpElses . forEach ( ( cpElse ) => cpElse . init ( ) ) ; this . directives . cpStyles . forEach ( ( cpStyle ) => cpStyle . init ( ) ) ; this . directives . cpClasses . forEach ( ( cpClass ) => cpClass . init ( ) ) ; this . directives . cpKeys . forEach ( ( cpKey ) => cpKey . init ( ) ) ; this . directives . cpDisables . forEach ( ( cpDisable ) => cpDisable . init ( ) ) ; this . directives . cpFocus . forEach ( ( cpFocus ) => cpFocus . init ( ) ) ; this . directives . cpHide . forEach ( ( cpHide ) => cpHide . init ( ) ) ; this . directives . cpBlur . forEach ( ( cpBlur ) => cpBlur . init ( ) ) ; this . directives . cpMouse . forEach ( ( cpMouse ) => cpMouse . init ( ) ) ; this . directives . cpChange . forEach ( ( cpChange ) => cpChange . init ( ) ) ; this . directives . cpAttrs . forEach ( ( cpAttr ) => cpAttr . init ( ) ) ; } method public reload ( ) { if ( ! this . renderedView ) { return ; } this . reloadDirectives ( ) ; this . reloadElementChildes ( this . element , Common . getScope ( this . element ) ) ; this . processInterpolation ( ) ; } description param element public processInterpolation ( ) { this . getNodeTexts ( ) . forEach ( ( nodeTextReference ) => this . interpolation ( nodeTextReference ) ) ; } public getNodeTexts ( ) { let n ; const a = [ ] , walk = document . createTreeWalker ( this . element , NodeFilter . SHOW_TEXT , null , false ) ; while ( n = walk . nextNode ( ) ) { a . push ( n ) ; } return a ; } public getInterpolationValue ( content , childNode ) { try { return Common . evalInMultiContext ( childNode , content . trim ( ) . startsWith ( ':' ) ? content . trim ( ) . slice ( 1 ) : content , undefined ) + '' ; } catch ( e ) { return '' ; } } description param childNode public interpolation ( childNode ) { if ( ! Common . parentHasIgnore ( childNode ) ) { childNode . originalValue = childNode . originalValue || childNode . nodeValue ; childNode . $immutableInterpolation = childNode . $immutableInterpolation || false ; if ( childNode . $immutableInterpolation ) { return ; } let nodeModified = childNode . originalValue , str = childNode . originalValue ; str = Capivara . replaceAll ( str , Constants . START_INTERPOLATION , '{{' ) ; str = Capivara . replaceAll ( str , Constants . END_INTERPOLATION , '}}' ) ; ( str . match ( this . regexInterpolation ) || [ ] ) . forEach ( ( key ) => { const content = key . replace ( '{{' , '' ) . replace ( '}}' , '' ) ; if ( ! childNode . $immutableInterpolation ) { try { const evalValue = this . getInterpolationValue ( content , childNode ) ; key = Capivara . replaceAll ( key , '{{' , Constants . START_INTERPOLATION ) ; key = Capivara . replaceAll ( key , '}}' , Constants . END_INTERPOLATION ) ; nodeModified = nodeModified . replace ( key , evalValue ) ; childNode . nodeValue = nodeModified ; } catch ( e ) { } } if ( content . trim ( ) . startsWith ( ':' ) && ! childNode . $immutableInterpolation ) { childNode . $immutableInterpolation = true ; } } ) ; childNode . nodeValue = childNode . nodeValue . replace ( this . regexInterpolation , '' ) ; } } method public getCpModels ( ) { return this . directives . cpModels ; } method param capivaraBind public addCpModels ( capivaraBind ) { this . directives . cpModelsElements [ capivaraBind . attribute ] = this . directives . cpModelsElements [ capivaraBind . attribute ] || [ ] ; this . directives . cpModelsElements [ capivaraBind . attribute ] . push ( capivaraBind ) ; } param child public createCPModel ( child ) { this . directives . cpModels . push ( new CPModel ( child , this ) ) ; } param child public createCPClick ( child ) { this . directives . cpClicks . push ( new CPClick ( child , this ) ) ; } param child public createCPShow ( child ) { this . directives . cpShows . push ( new CPShow ( child , this ) ) ; } param child public createCPIf ( child ) { this . directives . cpIfs . push ( new CPIf ( child , this ) ) ; } param child public createCPElse ( child ) { this . directives . cpElses . push ( new CPElse ( child , this ) ) ; } param child public createCPElseIf ( child ) { this . directives . cpElseIfs . push ( new CPElseIf ( child , this ) ) ; } param child public createCPRepeat ( child ) { this . directives . repeats . push ( new CPRepeat ( child , this ) ) ; } param child public createCPInit ( child ) { this . directives . cpInits . push ( new CPInit ( child , this ) ) ; } param child public createCPStyle ( child ) { this . directives . cpStyles . push ( new CPStyle ( child , this ) ) ; } param child public createCPClass ( child ) { this . directives . cpClasses . push ( new CPClass ( child , this ) ) ; } param child public createCPKey ( child ) { this . directives . cpKeys . push ( new CPKey ( child , this ) ) ; } param child public createCPAttr ( child ) { this . directives . cpAttrs . push ( new CPAttr ( child , this ) ) ; } param child public createCPDisabled ( child ) { this . directives . cpDisables . push ( new CPDisabled ( child , this ) ) ; } param child public createCPFocus ( child ) { this . directives . cpFocus . push ( new CPFocus ( child , this ) ) ; } param child public createCPHide ( child ) { this . directives . cpHide . push ( new CPHide ( child , this ) ) ; } param child public createCPBlur ( child ) { this . directives . cpBlur . push ( new CPBlur ( child , this ) ) ; } param child public createCPmouse ( child ) { this . directives . cpMouse . push ( new CPMouse ( child , this ) ) ; } param child public createCPChange ( child ) { this . directives . cpChange . push ( new CPChange ( child , this ) ) ; } }