11import * as React from 'react'
2- import { ASTElement , Attributes , NodeType } from './ast'
2+ import { getAttributes , NodeType } from './dom'
3+
4+ export interface Attributes { [ keyof : string ] : string }
35
46const reactAttributesMap : Attributes = {
57 acceptcharset : 'acceptCharset' ,
@@ -49,12 +51,10 @@ const reactAttributesMap: Attributes = {
4951 usemap : 'useMap' ,
5052}
5153
52- function transformAttributes ( attributes ?: Attributes ) : Attributes {
53- if ( ! attributes ) {
54- return null
55- }
56-
54+ function transformAttributes ( attributesMap : NamedNodeMap ) : Attributes {
55+ const attributes = getAttributes ( attributesMap )
5756 const transformedAttributes : Attributes = { }
57+
5858 Object . keys ( attributes ) . forEach ( ( key ) => {
5959 if ( ! key . startsWith ( 'on' ) ) {
6060 if ( reactAttributesMap [ key ] ) {
@@ -67,38 +67,40 @@ function transformAttributes(attributes?: Attributes): Attributes {
6767 return transformedAttributes
6868}
6969
70- function transformChildren ( children ?: ASTElement [ ] ) {
71- return children || [ ]
70+ function renderTextNode ( node : Node & ChildNode ) {
71+ return node . nodeValue
7272}
7373
74- export function transform ( element : ASTElement ) {
75- return {
76- ... element ,
77- attributes : transformAttributes ( element . attributes ) ,
78- children : transformChildren ( element . children ) ,
74+ function renderElementNode ( node : Node & ChildNode ) {
75+ const element = transform ( node as Element )
76+
77+ if ( element . childNodes ) {
78+ return React . createElement ( element . nodeName , element . attributes , render ( element . childNodes ) )
7979 }
80+ return React . createElement ( element . nodeName , element . attributes )
8081}
8182
82- export function renderElement ( element : ASTElement ) : React . ReactNode {
83- if ( element . type === NodeType . TEXT_NODE ) {
84- return element . value
85- } else if ( element . type === NodeType . ELEMENT_NODE ) {
86- const children = element . value ? [
87- element . value ,
88- ...renderElements ( element . children ) ,
89- ] : renderElements ( element . children )
90- return React . createElement ( element . name , element . attributes , children )
83+ function transform ( element : Element ) {
84+ return {
85+ attributes : transformAttributes ( element . attributes ) ,
86+ childNodes : element . childNodes ,
87+ nodeName : element . nodeName ,
88+ nodeType : element . nodeType ,
89+ nodeValue : element . nodeValue ,
9190 }
92-
93- return null
9491}
9592
96- export function renderElements ( ast : ASTElement [ ] ) : React . ReactNode [ ] {
97- return ast . reduce ( ( elements , element ) => {
98- // Only keep text and tags. Remove everything else
99- if ( element . type === NodeType . ELEMENT_NODE || element . type === NodeType . TEXT_NODE ) {
100- elements . push ( renderElement ( transform ( element ) ) )
93+ export function render ( nodes : NodeListOf < Node & ChildNode > ) : React . ReactNode [ ] {
94+ const elements = [ ]
95+ for ( let i = 0 ; i < nodes . length ; i ++ ) {
96+ const node = nodes . item ( i )
97+
98+ if ( node . nodeType === NodeType . TEXT_NODE ) {
99+ elements . push ( renderTextNode ( node ) )
100+ } else if ( node . nodeType === NodeType . ELEMENT_NODE ) {
101+ elements . push ( renderElementNode ( node ) )
101102 }
102- return elements
103- } , [ ] )
103+ }
104+
105+ return elements
104106}
0 commit comments