import { Renderer , Vnode , parseTemplateToVnode , ParseOptions } from '@indiv/core' ; import { _document } from './document' ; export param { Element } nativeElement returns { string } export function getTemplate ( nativeElement ) { const copyElement = nativeElement . cloneNode ( ) ; const tagName = nativeElement . tagName . toLocaleLowerCase ( ) ; let tmpNode = _document . createElement ( 'div' ) ; tmpNode . appendChild ( copyElement ) ; const template = tmpNode . innerHTML ; tmpNode = null ; nativeElement = null ; if ( new RegExp ( `^\<${ tagName }.*\>\<\/${ tagName }\>$` ) . test ( template ) ) return template . split ( `</${ tagName }>` ) [ 0 ] ; return template ; } export param { Element } nativeElement param { Vnode [ ] } vnodeList param { Vnode } parentVnode param { ParseOptions } parseVnodeOptions export function parseNativeElementToVnode ( nativeElement , vnodeList , parentVnode , parseVnodeOptions ? ) { let type = 'text' ; if ( nativeElement . nodeType === 1 ) type = 'tag' ; if ( nativeElement . nodeType === 1 && nativeElement . tagName && parseVnodeOptions . components . indexOf ( nativeElement . tagName . toLocaleLowerCase ( ) ) !== - 1 ) type = 'component' ; let voidElement = false ; if ( type === 'text' || ! nativeElement . hasChildNodes ( ) ) voidElement = true ; const newVnode = new Vnode ( { tagName : type !== 'text' ? nativeElement . tagName . toLocaleLowerCase ( ) : null , nativeElement , parentVnode , attributes : [ ] , nodeValue : type === 'text' ? nativeElement . nodeValue : null , childNodes : type !== 'text' ? [ ] : null , type , value : type !== 'text' && ( nativeElement . tagName . toLocaleLowerCase ( ) === 'input' || nativeElement . tagName . toLocaleLowerCase ( ) === 'textarea' ) ? ( nativeElement as HTMLInputElement ) . value : null , repeatData : null , eventTypes : [ ] , key : null , checked : false , voidElement , template : type === 'text' ? nativeElement . nodeValue : getTemplate ( nativeElement ) , } ) ; vnodeList . push ( newVnode ) ; if ( type !== 'component' && nativeElement . hasChildNodes ( ) ) Array . from ( nativeElement . childNodes ) . forEach ( child => parseNativeElementToVnode ( child as Element , newVnode . childNodes , newVnode , parseVnodeOptions ) ) ; } export class extends Renderer export class PlatfromServerRenderer extends Renderer { public nativeElementToVnode ( nativeElement , parseVnodeOptions ? ) { if ( ! nativeElement . hasChildNodes ( ) ) return parseTemplateToVnode ( nativeElement . innerHTML , parseVnodeOptions ) ; const vnodeList = [ ] ; Array . from ( nativeElement . childNodes ) . forEach ( child => parseNativeElementToVnode ( child as Element , vnodeList , null , parseVnodeOptions ) ) ; return vnodeList ; } public getElementsByTagName ( name , master ? ) { if ( master ) return ( master as Element ) . getElementsByTagName ( name ) ; else return _document . getElementsByTagName ( name ) ; } public getElementByQuery ( name , master ? ) { if ( master ) return ( master as Element ) . querySelector ( name ) ; else return _document . querySelector ( name ) ; } public getAllElementsByQuery ( name , master ? ) { if ( master ) return ( master as Element ) . querySelectorAll ( name ) ; else return _document . querySelectorAll ( name ) ; } public hasChildNodes ( nativeElement ) { return nativeElement . hasChildNodes ( ) ; } public getChildNodes ( nativeElement ) { const childNodes = [ ] ; if ( nativeElement . hasChildNodes ( ) ) Array . from ( nativeElement . childNodes ) . forEach ( child => childNodes . push ( child as Element ) ) ; return childNodes ; } public removeChild ( parent , child ) { if ( parent . contains ( child ) ) { ( parent as Element ) . removeChild ( child as Element ) ; } } public appendChild ( parent , child ) { ( parent as Element ) . appendChild ( child as Element ) ; } public insertBefore ( parent , child , index ) { parent . insertBefore ( child , parent . childNodes [ index ] ) ; } public isContainted ( parent , child ) { return parent . contains ( child ) ; } public creatElement ( tagName ) { return _document . createElement ( tagName . toLocaleUpperCase ( ) ) ; } public creatTextElement ( value ) { return _document . createTextNode ( value ) ; } public creatCommentElement ( value ) { return _document . createComment ( value ) ; } public getAttribute ( element , name ) { return element . getAttribute ( name ) ; } public setNvAttribute ( element , name , value ) { const blackListAttr = [ 'nv-text' , 'nv-if' , 'nv-if-not' , 'nv-repeat' , 'nv-model' , 'nv-key' ] ; if ( blackListAttr . indexOf ( name ) !== - 1 ) return ; switch ( name ) { case 'nv-html' : { element . innerHTML = typeof value === 'undefined' ? '' : value ; break ; } case 'nv-class' : { if ( Array . isArray ( value ) ) element . classList . add ( ... value . map ( ( _value ) => String ( _value ) . trim ( ) ) ) ; else if ( String ( value ) . trim ( ) ) element . classList . add ( String ( value ) . trim ( ) ) ; break ; } default : { const attrName = name . replace ( 'nv-' , '' ) ; element . setAttribute ( attrName , value ) ; } } } public setAttribute ( element , name , value ) { element . setAttribute ( name , value ) ; } public removeNvAttribute ( element , name , value ? ) { const blackListAttr = [ 'nv-text' , 'nv-if' , 'nv-if-not' , 'nv-repeat' , 'nv-model' , 'nv-key' ] ; if ( blackListAttr . indexOf ( name ) !== - 1 ) return ; switch ( name ) { case 'nv-html' : { element . innerHTML = '' ; break ; } case 'nv-class' : { if ( Array . isArray ( value ) ) element . classList . remove ( ... value . map ( ( _value ) => String ( _value ) . trim ( ) ) ) ; else if ( String ( value ) . trim ( ) ) element . classList . remove ( String ( value ) . trim ( ) ) ; break ; } default : { const attrName = name . replace ( 'nv-' , '' ) ; element . removeAttribute ( attrName ) ; } } } public removeAttribute ( element , name , value ? ) { element . removeAttribute ( name ) ; } public setNodeValue ( element , nodeValue ) { element . nodeValue = nodeValue ; } public setValue ( element , value ) { element . value = value ; } public removeEventListener ( element , eventType , handler ) { element . removeEventListener ( eventType , handler ) ; } public addEventListener ( element , eventType , handler ) { element . addEventListener ( eventType , handler ) ; } public setStyle ( element , name , value ) { element . style [ name as any ] = value ; } public removeStyle ( element , name ) { element . style [ name as any ] = "" ; } public getStyle ( element , name ) { return element . style [ name as any ] ; } }