nl_tokens: / * ▄████▄ ▄████▄ ▄████▄ ██ ██ ██████ ██ ▀▀ ██▄▄██ ██ ▀▀ ██▄▄██ ██▄▄ ██ ▄▄ ██▀▀██ ██ ▄▄ ██▀▀██ ██▀▀ ▀████▀ ██ ██ ▀████▀ ██ ██ ██████
pl_tokens: function ( c , callback , $tbodies ) { var cache , val , txt , rowIndex , colIndex , tbodyIndex , $tbody , $row , cols , $cells , cell , cacheTime , totalRows , rowData , prevRowData , colMax , span , cacheIndex , hasParser , <mask> , len , index , table = c . table , parsers = c . parsers ; // update tbody variable c . $tbodies = c . $table . children ( 'tbody:not(.' + c . cssInfoBlock + ')' ) ; $tbody = typeof $tbodies === 'undefined' ? c . $tbodies : $tbodies , c . cache = { } ; c . totalRows = 0 ; // if no parsers found, return - it's an empty table. if ( ! parsers ) { return c . debug ? console . warn ( 'Warning: *Empty table!* Not building a cache' ) : '' ; } if ( c . debug ) { cacheTime = new Date ( ) ; } // processing icon if ( c . showProcessing ) { ts . isProcessing ( table , true ) ; } for ( tbodyIndex = 0 ; tbodyIndex < $tbody . length ; tbodyIndex ++ ) { colMax = [ ] ; // column max value per tbody cache = c . cache [ tbodyIndex ] = { normalized : [ ] // array of normalized row data; last entry contains 'rowData' above // colMax: #   // added at the end } ; totalRows = ( $tbody [ tbodyIndex ] && $tbody [ tbodyIndex ] . rows . length ) || 0 ; for ( rowIndex = 0 ; rowIndex < totalRows ; ++ rowIndex ) { rowData = { // order: original row order # // $row : jQuery Object[] child : [ ] , // child row text (filter widget) raw : [ ] // original row text } ; /** Add the table data to main data array */ $row = $ ( $tbody [ tbodyIndex ] . rows [ rowIndex ] ) ; cols = [ ] ; // if this is a child row, add it to the last row's children and continue to the next row // ignore child row class, if it is the first row if ( $row . hasClass ( c . cssChildRow ) && rowIndex !== 0 ) { len = cache . normalized . length - 1 ; prevRowData = cache . normalized [ len ] [ c . columns ] ; prevRowData . $row = prevRowData . $row . add ( $row ) ; // add 'hasChild' class name to parent row if ( ! $row . prev ( ) . hasClass ( c . cssChildRow ) ) { $row . prev ( ) . addClass ( ts . css . cssHasChild ) ; } // save child row content (un-parsed!) $cells = $row . children ( 'th, td' ) ; len = prevRowData . child . length ; prevRowData . child [ len ] = [ ] ; // child row content does not account for colspans/rowspans; so indexing may be off cacheIndex = 0 ; max = c . columns ; for ( colIndex = 0 ; colIndex < max ; colIndex ++ ) { cell = $cells [ colIndex ] ; if ( cell ) { prevRowData . child [ len ] [ colIndex ] = ts . getParsedText ( c , cell , colIndex ) ; span = $cells [ colIndex ] . colSpan - 1 ; if ( span > 0 ) { cacheIndex += span ; max += span ; } } cacheIndex ++ ; } // go to the next for loop continue ; } rowData . $row = $row ; rowData . order = rowIndex ; // add original row position to rowCache cacheIndex = 0 ; max = c . columns ; for ( colIndex = 0 ; colIndex < max ; ++ colIndex ) { cell = $row [ 0 ] . cells [ colIndex ] ; if ( cell && cacheIndex < c . columns ) { hasParser = typeof parsers [ cacheIndex ] !== 'undefined' ; if ( ! hasParser && c . debug ) { console . warn ( 'No parser found for row: ' + rowIndex + ', column: ' + colIndex + '; cell containing: "' + $ ( cell ) . text ( ) + '"; does it have a header?' ) ; } val = ts . getElementText ( c , cell , cacheIndex ) ; rowData . raw [ cacheIndex ] = val ; // save original row text // save raw column text even if there is no parser set txt = ts . getParsedText ( c , cell , cacheIndex , val ) ; cols [ cacheIndex ] = txt ; if ( hasParser && ( parsers [ cacheIndex ] . type || '' ) . toLowerCase ( ) === 'numeric' ) { // determine column max value (ignore sign) colMax [ cacheIndex ] = Math . max ( Math . abs ( txt ) || 0 , colMax [ cacheIndex ] || 0 ) ; } // allow colSpan in tbody span = cell . colSpan - 1 ; if ( span > 0 ) { index = 0 ; while ( index <= span ) { // duplicate text (or not) to spanned columns // instead of setting duplicate span to empty string, use textExtraction to try to get a value // see http://stackoverflow.com/q/36449711/145346 txt = c . duplicateSpan || index === 0 ? val : typeof c . textExtraction !== 'string' ? ts . getElementText ( c , cell , cacheIndex + index ) || '' : '' ; rowData . raw [ cacheIndex + index ] = txt ; cols [ cacheIndex + index ] = txt ; index ++ ; } cacheIndex += span ; max += span ; } } cacheIndex ++ ; } // ensure rowData is always in the same location (after the last column) cols [ c . columns ] = rowData ; cache . normalized [ cache . normalized . length ] = cols ; } cache . colMax = colMax ; // total up rows, not including child rows c . totalRows += cache . normalized . length ; } if ( c . showProcessing ) { ts . isProcessing ( table ) ; // remove processing icon } if ( c . debug ) { len = Math . min ( 5 , c . cache [ 0 ] . normalized . length ) ; console [ console . group ? 'group' : 'log' ] ( 'Building cache for ' + c . totalRows + ' rows (showing ' + len + ' rows in log)' + ts . benchmark ( cacheTime ) ) ; val = { } ; for ( colIndex = 0 ; colIndex < c . columns ; colIndex ++ ) { for ( cacheIndex = 0 ; cacheIndex < len ; cacheIndex ++ ) { if ( ! val [ 'row: ' + cacheIndex ] ) { val [ 'row: ' + cacheIndex ] = { } ; } val [ 'row: ' + cacheIndex ] [ c . $headerIndexed [ colIndex ] . text ( ) ] = c . cache [ 0 ] . normalized [ cacheIndex ] [ colIndex ] ; } } console [ console . table ? 'table' : 'log' ] ( val ) ; if ( console . groupEnd ) { console . groupEnd ( ) ; } } if ( $ . isFunction ( callback ) ) { callback ( table ) ; } }