@@ -924,49 +924,90 @@ function renderLayout(data: DiagnosticsData): void {
924924 const reportTabContent = document . getElementById ( 'tab-report' ) ;
925925 if ( reportTabContent ) {
926926 const sorted = [ ...message . sessionFolders ] . sort ( ( a : any , b : any ) => b . count - a . count ) ;
927- let sessionFilesHtml = `
928- <div class="session-folders-table">
929- <h4>Main Session Folders (by editor root):</h4>
930- <table class="session-table">
931- <thead>
932- <tr>
933- <th>Folder</th>
934- <th>Editor</th>
935- <th># of Sessions</th>
936- <th>Open</th>
937- </tr>
938- </thead>
939- <tbody>` ;
927+
928+ // Build the session folders table using DOM APIs to avoid HTML injection
929+ const container = document . createElement ( 'div' ) ;
930+ container . className = 'session-folders-table' ;
931+
932+ const heading = document . createElement ( 'h4' ) ;
933+ heading . textContent = 'Main Session Folders (by editor root):' ;
934+ container . appendChild ( heading ) ;
935+
936+ const table = document . createElement ( 'table' ) ;
937+ table . className = 'session-table' ;
938+ container . appendChild ( table ) ;
939+
940+ const thead = document . createElement ( 'thead' ) ;
941+ table . appendChild ( thead ) ;
942+ const headerRow = document . createElement ( 'tr' ) ;
943+ thead . appendChild ( headerRow ) ;
944+
945+ const headers = [ 'Folder' , 'Editor' , '# of Sessions' , 'Open' ] ;
946+ headers . forEach ( ( text ) => {
947+ const th = document . createElement ( 'th' ) ;
948+ th . textContent = text ;
949+ headerRow . appendChild ( th ) ;
950+ } ) ;
951+
952+ const tbody = document . createElement ( 'tbody' ) ;
953+ table . appendChild ( tbody ) ;
954+
940955 sorted . forEach ( ( sf : any ) => {
941956 let display = sf . dir ;
942957 const home = ( window as any ) . process ?. env ?. HOME || ( window as any ) . process ?. env ?. USERPROFILE || '' ;
943958 if ( home && display . startsWith ( home ) ) {
944959 display = display . replace ( home , '~' ) ;
945960 }
946961 const editorName = sf . editorName || 'Unknown' ;
947- sessionFilesHtml += `
948- <tr>
949- <td title="${ escapeHtml ( sf . dir ) } ">${ escapeHtml ( display ) } </td>
950- <td><span class="editor-badge">${ escapeHtml ( editorName ) } </span></td>
951- <td>${ sf . count } </td>
952- <td><a href="#" class="reveal-link" data-path="${ encodeURIComponent ( sf . dir ) } ">Open directory</a></td>
953- </tr>` ;
962+
963+ const row = document . createElement ( 'tr' ) ;
964+
965+ // Folder cell
966+ const folderCell = document . createElement ( 'td' ) ;
967+ folderCell . setAttribute ( 'title' , escapeHtml ( sf . dir ) ) ;
968+ folderCell . textContent = escapeHtml ( display ) ;
969+ row . appendChild ( folderCell ) ;
970+
971+ // Editor cell
972+ const editorCell = document . createElement ( 'td' ) ;
973+ const editorBadge = document . createElement ( 'span' ) ;
974+ editorBadge . className = 'editor-badge' ;
975+ editorBadge . textContent = escapeHtml ( editorName ) ;
976+ editorCell . appendChild ( editorBadge ) ;
977+ row . appendChild ( editorCell ) ;
978+
979+ // Count cell
980+ const countCell = document . createElement ( 'td' ) ;
981+ countCell . textContent = String ( sf . count ) ;
982+ row . appendChild ( countCell ) ;
983+
984+ // Open link cell
985+ const openCell = document . createElement ( 'td' ) ;
986+ const link = document . createElement ( 'a' ) ;
987+ link . href = '#' ;
988+ link . className = 'reveal-link' ;
989+ link . setAttribute ( 'data-path' , encodeURIComponent ( sf . dir ) ) ;
990+ link . textContent = 'Open directory' ;
991+ openCell . appendChild ( link ) ;
992+ row . appendChild ( openCell ) ;
993+
994+ tbody . appendChild ( row ) ;
954995 } ) ;
955- sessionFilesHtml += `
956- </tbody>
957- </table>
958- </div>` ;
959-
996+
960997 // Find where to insert or replace the session folders table
961998 // It should be inserted after the report-content div but before the button-group
962999 const existingTable = reportTabContent . querySelector ( '.session-folders-table' ) ;
963- if ( existingTable ) {
964- existingTable . outerHTML = sessionFilesHtml ;
1000+ if ( existingTable && existingTable . parentNode ) {
1001+ existingTable . parentNode . replaceChild ( container , existingTable ) ;
9651002 } else {
9661003 // Insert after the report-content div
9671004 const reportContent = reportTabContent . querySelector ( '.report-content' ) ;
968- if ( reportContent ) {
969- reportContent . insertAdjacentHTML ( 'afterend' , sessionFilesHtml ) ;
1005+ if ( reportContent && reportContent . parentNode ) {
1006+ if ( reportContent . nextSibling ) {
1007+ reportContent . parentNode . insertBefore ( container , reportContent . nextSibling ) ;
1008+ } else {
1009+ reportContent . parentNode . appendChild ( container ) ;
1010+ }
9701011 }
9711012 }
9721013 setupStorageLinkHandlers ( ) ;
0 commit comments