'use strict' ; import type DataEventEmitter from '../DataEventEmitter' ; import DataParser from './DataParser.js' ; import DataTable from '../DataTable.js' ; import DataConverter from '../DataConverter.js' ; import U from '../../Core/Utilities.js' ; const { merge } = U ; private class HTMLTableParser extends DataParser < DataParser . Event > { /**
     * Default options
     */ protected static readonly defaultOptions : ( HTMLTableParser . ClassJSONOptions ) = { ... DataParser . defaultOptions } ; param { HTMLTableParser . OptionsType } options param { HTMLElement | null } tableElement param { DataConverter } converter constructor ( options ? , tableElement = null , converter ? ) { super ( ) ; this . columns = [ ] ; this . headers = [ ] ; this . options = merge ( HTMLTableParser . defaultOptions , options ) ; this . converter = converter || new DataConverter ( ) ; if ( tableElement ) { this . tableElement = tableElement ; this . tableElementID = tableElement . id ; } else if ( options && options . tableHTML ) { this . tableElement = options . tableHTML ; this . tableElementID = options . tableHTML . id ; } } private columns : DataTable . CellType [ ] [ ] ; private headers : string [ ] ; public converter : DataConverter ; public options : HTMLTableParser . ClassJSONOptions ; public tableElement ? : HTMLElement ; public tableElementID ? : string ; param { HTMLTableParser . OptionsType } options param { DataEventEmitter . EventDetail } eventDetail emits emits emits public parse ( options , eventDetail ? ) { const parser = this , converter = this . converter , columns = [ ] , headers = [ ] , parseOptions = merge ( parser . options , options ) , { endRow , startColumn , endColumn , firstRowAsNames } = parseOptions , tableHTML = parseOptions . tableHTML || this . tableElement ; if ( ! ( tableHTML instanceof HTMLElement ) ) { parser . emit < DataParser . Event > ( { type : 'parseError' , columns , detail : eventDetail , headers , error : 'Not a valid HTML Table' } ) ; return ; } parser . tableElement = this . tableElement ; parser . tableElementID = tableHTML . id ; this . emit < DataParser . Event > ( { type : 'parse' , columns : parser . columns , detail : eventDetail , headers : parser . headers } ) ; const rows = tableHTML . getElementsByTagName ( 'tr' ) , rowsCount = rows . length ; let rowIndex = 0 , item , { startRow } = parseOptions ; if ( firstRowAsNames && rowsCount ) { const items = rows [ 0 ] . children , itemsLength = items . length ; for ( let i = startColumn ; i < itemsLength ; i ++ ) { if ( i > endColumn ) { break ; } item = items [ i ] ; if ( item . tagName === 'TD' || item . tagName === 'TH' ) { headers . push ( item . innerHTML ) ; } } startRow ++ ; } while ( rowIndex < rowsCount ) { if ( rowIndex >= startRow && rowIndex <= endRow ) { const columnsInRow = rows [ rowIndex ] . children , columnsInRowLength = columnsInRow . length ; let columnIndex = 0 ; while ( columnIndex < columnsInRowLength ) { const relativeColumnIndex = columnIndex - startColumn , row = columns [ relativeColumnIndex ] ; item = columnsInRow [ columnIndex ] ; if ( ( item . tagName === 'TD' || item . tagName === 'TH' ) && ( columnIndex >= startColumn && columnIndex <= endColumn ) ) { if ( ! columns [ relativeColumnIndex ] ) { columns [ relativeColumnIndex ] = [ ] ; } let cellValue = converter . asGuessedType ( item . innerHTML ) ; if ( cellValue instanceof Date ) { cellValue = cellValue . getTime ( ) ; } columns [ relativeColumnIndex ] [ rowIndex - startRow ] = cellValue ; let i = 1 ; while ( rowIndex - startRow >= i && row [ rowIndex - startRow - i ] === void 0 ) { row [ rowIndex - startRow - i ] = null ; i ++ ; } } columnIndex ++ ; } } rowIndex ++ ; } this . columns = columns ; this . headers = headers ; this . emit < DataParser . Event > ( { type : 'afterParse' , columns , detail : eventDetail , headers } ) ; } return { DataTable } public getTable ( ) { return DataParser . getTableFromColumns ( this . columns , this . headers ) ; } } namespace HTMLTableParser { /**
     * The available options for the parser
     */ export type OptionsType = Partial < ParserOptions & DataParser . Options > ; /**
     * Options for the parser compatible with ClassJSON
     */ export interface ClassJSONOptions extends DataParser . Options { } /**
     * Options not compatible with ClassJSON
     */ export interface ParserOptions { tableHTML ? : ( HTMLElement | null ) ; } } export default HTMLTableParser ;