22// Use of this source code is governed by a BSD-style license that can be
33// found in the LICENSE file.
44/* eslint-disable rulesdir/no-imperative-dom-api */
5+ /* eslint-disable rulesdir/no-lit-render-outside-of-view */
56
67import * as Common from '../../core/common/common.js' ;
78import * as i18n from '../../core/i18n/i18n.js' ;
@@ -10,6 +11,7 @@ import * as TextUtils from '../../models/text_utils/text_utils.js';
1011import * as Workspace from '../../models/workspace/workspace.js' ;
1112import * as DataGrid from '../../ui/legacy/components/data_grid/data_grid.js' ;
1213import * as UI from '../../ui/legacy/legacy.js' ;
14+ import { Directives , html , nothing , render } from '../../ui/lit/lit.js' ;
1315
1416import coverageListViewStyles from './coverageListView.css.js' ;
1517import {
@@ -113,6 +115,7 @@ const UIStrings = {
113115} as const ;
114116const str_ = i18n . i18n . registerUIStrings ( 'panels/coverage/CoverageListView.ts' , UIStrings ) ;
115117const i18nString = i18n . i18n . getLocalizedString . bind ( undefined , str_ ) ;
118+ const { styleMap} = Directives ;
116119
117120export function coverageTypeToString ( type : CoverageType ) : string {
118121 const types = [ ] ;
@@ -179,17 +182,18 @@ export class CoverageListView extends UI.Widget.VBox {
179182 weight : 1 ,
180183 } ,
181184 ] as DataGrid . DataGrid . ColumnDescriptor [ ] ;
182- this . dataGrid = new DataGrid . SortableDataGrid . SortableDataGrid < GridNode > ( {
183- displayName : i18nString ( UIStrings . codeCoverage ) ,
184- columns,
185- refreshCallback : undefined ,
186- deleteCallback : undefined ,
187- } ) ;
185+ this . dataGrid =
186+ DataGrid . SortableDataGrid . SortableDataGrid . create ( [ 'dummy' ] , [ ] , i18nString ( UIStrings . codeCoverage ) ) as
187+ DataGrid . SortableDataGrid . SortableDataGrid < GridNode > ;
188+ this . dataGrid . removeColumn ( 'dummy' ) ;
189+ for ( const column of columns ) {
190+ this . dataGrid . addColumn ( column ) ;
191+ }
192+ this . dataGrid . setColumnsVisibility ( new Set ( columns . map ( column => column . id ) ) ) ;
188193 this . dataGrid . setResizeMethod ( DataGrid . DataGrid . ResizeMethod . LAST ) ;
189194 this . dataGrid . setStriped ( true ) ;
190195 this . dataGrid . element . classList . add ( 'flex-auto' ) ;
191196 this . dataGrid . addEventListener ( DataGrid . DataGrid . Events . OPENED_NODE , this . onOpenedNode , this ) ;
192- this . dataGrid . addEventListener ( DataGrid . DataGrid . Events . SORTING_CHANGED , this . sortingChanged , this ) ;
193197
194198 const dataGridWidget = this . dataGrid . asWidget ( ) ;
195199 dataGridWidget . show ( this . contentElement ) ;
@@ -222,7 +226,7 @@ export class CoverageListView extends UI.Widget.VBox {
222226 }
223227 }
224228 if ( hadUpdates ) {
225- this . sortingChanged ( ) ;
229+ this . dataGrid . dispatchEventToListeners ( DataGrid . DataGrid . Events . SORTING_CHANGED ) ;
226230 }
227231 }
228232
@@ -279,7 +283,7 @@ export class CoverageListView extends UI.Widget.VBox {
279283 }
280284 }
281285 if ( hadTreeUpdates ) {
282- this . sortingChanged ( ) ;
286+ this . dataGrid . dispatchEventToListeners ( DataGrid . DataGrid . Events . SORTING_CHANGED ) ;
283287 }
284288 }
285289
@@ -322,20 +326,6 @@ export class CoverageListView extends UI.Widget.VBox {
322326 void Common . Revealer . reveal ( sourceCode ) ;
323327 }
324328
325- private sortingChanged ( ) : void {
326- const columnId = this . dataGrid . sortColumnId ( ) ;
327- if ( ! columnId ) {
328- return ;
329- }
330- const sortFunction = GridNode . sortFunctionForColumn ( columnId ) as (
331- ( arg0 : DataGrid . SortableDataGrid . SortableDataGridNode < GridNode > ,
332- arg1 : DataGrid . SortableDataGrid . SortableDataGridNode < GridNode > ) => number ) |
333- null ;
334- if ( ! sortFunction ) {
335- return ;
336- }
337- this . dataGrid . sortNodes ( sortFunction , ! this . dataGrid . isSortOrderAscending ( ) ) ;
338- }
339329}
340330
341331let percentageFormatter : Intl . NumberFormat | null = null ;
@@ -372,6 +362,15 @@ export class GridNode extends DataGrid.SortableDataGrid.SortableDataGridNode<Gri
372362 this . url = coverageInfo . url ( ) ;
373363 this . maxSize = maxSize ;
374364 this . highlightRegExp = null ;
365+ this . #updateData( ) ;
366+ }
367+
368+ #updateData( ) : void {
369+ this . data [ 'url' ] = this . url ;
370+ this . data [ 'type' ] = coverageTypeToString ( this . coverageInfo . type ( ) ) ;
371+ this . data [ 'size' ] = this . coverageInfo . size ( ) ;
372+ this . data [ 'unused-size' ] = this . coverageInfo . unusedSize ( ) ;
373+ this . data [ 'bars' ] = this . coverageInfo . unusedSize ( ) ;
375374 }
376375
377376 setHighlight ( highlightRegExp : RegExp | null ) : void {
@@ -389,95 +388,91 @@ export class GridNode extends DataGrid.SortableDataGrid.SortableDataGridNode<Gri
389388 this . lastUsedSize = this . coverageInfo . usedSize ( ) ;
390389 this . maxSize = maxSize ;
391390 this . refresh ( ) ;
391+ this . #updateData( ) ;
392392 return true ;
393393 }
394394
395395 override createCell ( columnId : string ) : HTMLElement {
396396 const cell = this . createTD ( columnId ) ;
397+ const info = this . coverageInfo ;
398+ const formatBytes = ( value : number | undefined ) : string => {
399+ return getBytesFormatter ( ) . format ( value ?? 0 ) ;
400+ } ;
401+ const formatPercent = ( value : number | undefined ) : string => {
402+ return getPercentageFormatter ( ) . format ( value ?? 0 ) ;
403+ } ;
397404 switch ( columnId ) {
398405 case 'url' : {
399406 UI . Tooltip . Tooltip . install ( cell , this . url ) ;
400- const outer = cell . createChild ( 'div' , 'url-outer' ) ;
401- const prefix = outer . createChild ( 'div' , 'url-prefix' ) ;
402- const suffix = outer . createChild ( 'div' , 'url-suffix' ) ;
407+ this . setCellAccessibleName ( this . url , cell , columnId ) ;
403408 const splitURL = / ^ ( .* ) ( \/ [ ^ / ] * ) $ / . exec ( this . url ) ;
404- prefix . textContent = splitURL ? splitURL [ 1 ] : this . url ;
405- suffix . textContent = splitURL ? splitURL [ 2 ] : '' ;
409+ render (
410+ html `
411+ < div class ="url-outer ">
412+ < div class ="url-prefix "> ${ splitURL ? splitURL [ 1 ] : this . url } </ div >
413+ < div class ="url-suffix "> ${ splitURL ? splitURL [ 2 ] : '' } </ div >
414+ </ div > ` ,
415+ cell ) ;
406416 if ( this . highlightRegExp ) {
407- this . highlight ( outer , this . url ) ;
417+ this . highlight ( cell , this . url ) ;
408418 }
409- this . setCellAccessibleName ( this . url , cell , columnId ) ;
410419 break ;
411420 }
412421 case 'type' : {
413- cell . textContent = coverageTypeToString ( this . coverageInfo . type ( ) ) ;
414- if ( this . coverageInfo . type ( ) & CoverageType . JAVA_SCRIPT_PER_FUNCTION ) {
415- UI . Tooltip . Tooltip . install ( cell , i18nString ( UIStrings . jsCoverageWithPerFunction ) ) ;
416- } else if ( this . coverageInfo . type ( ) & CoverageType . JAVA_SCRIPT ) {
417- UI . Tooltip . Tooltip . install ( cell , i18nString ( UIStrings . jsCoverageWithPerBlock ) ) ;
418- }
422+ UI . Tooltip . Tooltip . install (
423+ cell ,
424+ info . type ( ) & CoverageType . JAVA_SCRIPT_PER_FUNCTION ? i18nString ( UIStrings . jsCoverageWithPerFunction ) :
425+ info . type ( ) & CoverageType . JAVA_SCRIPT ? i18nString ( UIStrings . jsCoverageWithPerBlock ) :
426+ '' ) ;
427+ render ( coverageTypeToString ( this . coverageInfo . type ( ) ) , cell ) ;
419428 break ;
420429 }
421430 case 'size' : {
422- const size = this . coverageInfo . size ( ) || 0 ;
423- const sizeSpan = cell . createChild ( 'span' ) ;
424- const sizeFormatted = getBytesFormatter ( ) . format ( size ) ;
425- sizeSpan . textContent = sizeFormatted ;
426- const sizeAccessibleName = i18nString ( UIStrings . sBytes , { n : size } ) ;
427- this . setCellAccessibleName ( sizeAccessibleName , cell , columnId ) ;
431+ this . setCellAccessibleName ( i18nString ( UIStrings . sBytes , { n : info . size ( ) || 0 } ) , cell , columnId ) ;
432+ render ( html `< span > ${ formatBytes ( info . size ( ) ) } </ span > ` , cell ) ;
428433 break ;
429434 }
430435 case 'unused-size' : {
431- const unusedSize = this . coverageInfo . unusedSize ( ) || 0 ;
432- const unusedSizeSpan = cell . createChild ( 'span' ) ;
433- const unusedPercentsSpan = cell . createChild ( 'span' , 'percent-value' ) ;
434- const unusedSizeFormatted = getBytesFormatter ( ) . format ( unusedSize ) ;
435- unusedSizeSpan . textContent = unusedSizeFormatted ;
436- const unusedPercentFormatted = getPercentageFormatter ( ) . format ( this . coverageInfo . unusedPercentage ( ) ) ;
437- unusedPercentsSpan . textContent = unusedPercentFormatted ;
438- const unusedAccessibleName = i18nString ( UIStrings . sBytesS , { n : unusedSize , percentage : unusedPercentFormatted } ) ;
439- this . setCellAccessibleName ( unusedAccessibleName , cell , columnId ) ;
436+ this . setCellAccessibleName (
437+ i18nString ( UIStrings . sBytesS , { n : info . unusedSize ( ) , percentage : formatPercent ( info . unusedPercentage ( ) ) } ) ,
438+ cell , columnId ) ;
439+ // clang-format off
440+ render ( html `
441+ < span > ${ formatBytes ( info . unusedSize ( ) ) } </ span >
442+ < span class ="percent-value ">
443+ ${ formatPercent ( info . unusedPercentage ( ) ) }
444+ </ span > ` , cell ) ;
445+ // clang-format on
440446 break ;
441447 }
442448 case 'bars' : {
443- const barContainer = cell . createChild ( 'div' , 'bar-container' ) ;
444- const unusedPercent = getPercentageFormatter ( ) . format ( this . coverageInfo . unusedPercentage ( ) ) ;
445- const usedPercent = getPercentageFormatter ( ) . format ( this . coverageInfo . usedPercentage ( ) ) ;
446- if ( this . coverageInfo . unusedSize ( ) > 0 ) {
447- const unusedSizeBar = barContainer . createChild ( 'div' , 'bar bar-unused-size' ) ;
448- unusedSizeBar . style . width = ( ( this . coverageInfo . unusedSize ( ) / this . maxSize ) * 100 || 0 ) + '%' ;
449- if ( this . coverageInfo . type ( ) & CoverageType . JAVA_SCRIPT_PER_FUNCTION ) {
450- UI . Tooltip . Tooltip . install (
451- unusedSizeBar ,
452- i18nString (
453- UIStrings . sBytesSBelongToFunctionsThatHave ,
454- { PH1 : this . coverageInfo . unusedSize ( ) , PH2 : unusedPercent } ) ) ;
455- } else if ( this . coverageInfo . type ( ) & CoverageType . JAVA_SCRIPT ) {
456- UI . Tooltip . Tooltip . install (
457- unusedSizeBar ,
458- i18nString (
459- UIStrings . sBytesSBelongToBlocksOf , { PH1 : this . coverageInfo . unusedSize ( ) , PH2 : unusedPercent } ) ) ;
460- }
461- }
462- if ( this . coverageInfo . usedSize ( ) > 0 ) {
463- const usedSizeBar = barContainer . createChild ( 'div' , 'bar bar-used-size' ) ;
464- usedSizeBar . style . width = ( ( this . coverageInfo . usedSize ( ) / this . maxSize ) * 100 || 0 ) + '%' ;
465- if ( this . coverageInfo . type ( ) & CoverageType . JAVA_SCRIPT_PER_FUNCTION ) {
466- UI . Tooltip . Tooltip . install (
467- usedSizeBar ,
468- i18nString (
469- UIStrings . sBytesSBelongToFunctionsThatHaveExecuted ,
470- { PH1 : this . coverageInfo . usedSize ( ) , PH2 : usedPercent } ) ) ;
471- } else if ( this . coverageInfo . type ( ) & CoverageType . JAVA_SCRIPT ) {
472- UI . Tooltip . Tooltip . install (
473- usedSizeBar ,
474- i18nString (
475- UIStrings . sBytesSBelongToBlocksOfJavascript ,
476- { PH1 : this . coverageInfo . usedSize ( ) , PH2 : usedPercent } ) ) ;
477- }
478- }
479449 this . setCellAccessibleName (
480- i18nString ( UIStrings . sOfFileUnusedSOfFileUsed , { PH1 : unusedPercent , PH2 : usedPercent } ) , cell , columnId ) ;
450+ i18nString (
451+ UIStrings . sOfFileUnusedSOfFileUsed ,
452+ { PH1 : formatPercent ( info . unusedPercentage ( ) ) , PH2 : formatPercent ( info . usedPercentage ( ) ) } ) ,
453+ cell , columnId ) ;
454+ // clang-format off
455+ render ( html `
456+ < div class ="bar-container ">
457+ ${ info . unusedSize ( ) > 0 ? html `
458+ < div class ="bar bar-unused-size "
459+ title =${
460+ info . type ( ) & CoverageType . JAVA_SCRIPT_PER_FUNCTION ? i18nString ( UIStrings . sBytesSBelongToFunctionsThatHave , { PH1 : info . unusedSize ( ) , PH2 : formatPercent ( info . unusedPercentage ( ) ) } ) :
461+ info . type ( ) & CoverageType . JAVA_SCRIPT ? i18nString ( UIStrings . sBytesSBelongToBlocksOf , { PH1 : info . unusedSize ( ) , PH2 : formatPercent ( info . unusedPercentage ( ) ) } ) :
462+ '' }
463+ style =${ styleMap ( { width : ( ( info . unusedSize ( ) / this . maxSize ) * 100 || 0 ) + '%' } ) } >
464+ </ div > ` : nothing }
465+ ${ info . usedSize ( ) > 0 ? html `
466+ < div class ="bar bar-used-size "
467+ title =${
468+ info . type ( ) & CoverageType . JAVA_SCRIPT_PER_FUNCTION ? i18nString ( UIStrings . sBytesSBelongToFunctionsThatHaveExecuted , { PH1 : info . usedSize ( ) , PH2 : formatPercent ( info . usedPercentage ( ) ) } ) :
469+ info . type ( ) & CoverageType . JAVA_SCRIPT ? i18nString ( UIStrings . sBytesSBelongToBlocksOfJavascript , { PH1 : info . usedSize ( ) , PH2 : formatPercent ( info . usedPercentage ( ) ) } ) :
470+ '' }
471+ { PH1: info.usedSize(), PH2: formatPercent(info.usedPercentage()) })}
472+ style =${ styleMap ( { width :( ( info . usedSize ( ) / this . maxSize ) * 100 || 0 ) + '%' } ) } >
473+ </ div > ` : nothing }
474+ </ div > ` , cell ) ;
475+ // clang-format on
481476 }
482477 }
483478 return cell ;
@@ -495,26 +490,4 @@ export class GridNode extends DataGrid.SortableDataGrid.SortableDataGridNode<Gri
495490 UI . UIUtils . highlightRangesWithStyleClass ( element , [ range ] , 'filter-highlight' ) ;
496491 }
497492
498- static sortFunctionForColumn ( columnId : string ) : ( ( arg0 : GridNode , arg1 : GridNode ) => number ) | null {
499- const compareURL = ( a : GridNode , b : GridNode ) : number => a . url . localeCompare ( b . url ) ;
500- switch ( columnId ) {
501- case 'url' :
502- return compareURL ;
503- case 'type' :
504- return ( a : GridNode , b : GridNode ) => {
505- const typeA = coverageTypeToString ( a . coverageInfo . type ( ) ) ;
506- const typeB = coverageTypeToString ( b . coverageInfo . type ( ) ) ;
507- return typeA . localeCompare ( typeB ) || compareURL ( a , b ) ;
508- } ;
509- case 'size' :
510- return ( a : GridNode , b : GridNode ) => a . coverageInfo . size ( ) - b . coverageInfo . size ( ) || compareURL ( a , b ) ;
511- case 'bars' :
512- case 'unused-size' :
513- return ( a : GridNode , b : GridNode ) =>
514- a . coverageInfo . unusedSize ( ) - b . coverageInfo . unusedSize ( ) || compareURL ( a , b ) ;
515- default :
516- console . assert ( false , 'Unknown sort field: ' + columnId ) ;
517- return null ;
518- }
519- }
520493}
0 commit comments