import sax from 'sax' ; import { VNodeElement , VNodeText } from './vdom.js' ; export class VNodeParser { root : VNodeElement ; tree : VNodeElement [ ] ; static parse ( xml ) { return new VNodeParser ( ) . parse ( xml ) ; } constructor ( ) { this . tree = [ ] ; } get currentNode ( ) : VNodeElement { return this . tree [ this . tree . length - 1 ] ; } parse ( xml ) { const parser = sax . parser ( true ) ; parser . ontext = ( text ) : void => { if ( text . trim ( ) === '' ) return ; const textNode = new VNodeText ( text ) ; this . currentNode . children . push ( textNode ) ; } ; parser . onopentag = ( tag ) : void => { const currentNode = new VNodeElement ( tag . name , tag . attributes as any , [ ] ) ; if ( this . tree . length > 0 ) { this . currentNode . children . push ( currentNode ) ; } else { this . root = currentNode ; } this . tree . push ( currentNode ) ; } ; parser . onclosetag = ( tag ) : void => { const lastNode = this . tree . pop ( ) ; if ( lastNode ?. tag !== tag ) throw new Error ( `Tag missmatch: ${ tag }` ) ; } ; return new Promise ( ( resolve ) => { parser . onend = ( ) : void => resolve ( this . root ) ; parser . write ( xml . trim ( ) ) . close ( ) ; } ) ; } }