import { Component , h , ComponentInterface , Prop , Host } from '@stencil/core' ; interface Attributes { [ propName ] : string | { [ propName ] : string ; } ; } interface NodeType { name : string ; attrs ? : Attributes ; children ? : ElementType [ ] ; } interface TextType { type : 'text' ; text : string ; } type ElementType = NodeType | TextType ; type StringType = string ; export type Nodes = ElementType [ ] | StringType ; @ Component ( { tag : 'taro-rich-text-core' } ) export class RichText implements ComponentInterface { @ Prop ( ) nodes : Nodes ; renderNode = ( node ) => { if ( 'type' in node && node . type === 'text' ) { const content = ( node . text || '' ) . replace ( /&nbsp;/g , '\u00A0' ) ; return content ; } else if ( 'name' in node && node . name ) { const { name , attrs , children } = node ; const attributes = { } ; let childList = [ ] ; if ( attrs && typeof attrs === 'object' ) { for ( const key in attrs ) { const val = attrs [ key ] ; if ( key === 'style' && typeof val === 'string' ) { const styles = val . split ( ';' ) . map ( item => item . trim ( ) ) . filter ( item => item ) ; const styleObj = { } ; styles . forEach ( item => { if ( ! item ) return ; const res = /(.+): *(.+)/g . exec ( item ) ; if ( ! res ) return ; const [ , name , value ] = res ; const styleName = name . replace ( /-([a-z])/g , ( ... args ) => args [ 1 ] . toUpperCase ( ) ) ; styleObj [ styleName ] = value ; } ) ; if ( Object . keys ( styleObj ) . length ) { attributes . style = styleObj ; } continue ; } attributes [ key ] = val ; } } if ( children && children . length ) { childList = children . map ( node => this . renderNode ( node ) ) ; } return h ( name , attributes , childList ) ; } return null ; } ; render ( ) { const { nodes , renderNode } = this ; if ( Array . isArray ( nodes ) ) { return ( < Host > { nodes . map ( node => renderNode ( node ) ) } < /Host>); } else { return < Host innerHTML = { nodes } />; } } }