1/** 2 * B2G Spec Table - Dynamic Data Bar Sizing 3 * Calculates relative widths based on numeric values (Excel-style) 4 * Supports both column-based (default) and group-based (for transposed tables) 5 */ 6 7(function() { 8 'use strict'; 9 10 /** 11 * Extract numeric value from cell content 12 * Handles formats like: "24/32T (8P+16E)", "16384", "2.6 GHz", "512-bit", "$1999" 13 */ 14 function extractNumericValue(text) { 15 if (!text) return 0; 16 17 // Remove HTML tags and trim 18 text = text.replace(/<[^>]*>/g, '').trim(); 19 20 // Remove currency symbols and common units 21 text = text.replace(/[$£â¬Â¥,]/g, ''); 22 23 // Extract first number (handles "24/32T" -> 24, "16384" -> 16384, etc.) 24 const match = text.match(/(\d+\.?\d*)/); 25 return match ? parseFloat(match[1]) : 0; 26 } 27 28 /** 29 * Process data bars by group (for transposed tables) 30 */ 31 function processDataBarsByGroup(table) { 32 // Collect all cells with data-group attribute 33 const groupedCells = {}; 34 35 table.querySelectorAll('td[data-group][data-level]').forEach(cell => { 36 const group = cell.getAttribute('data-group'); 37 const value = extractNumericValue(cell.textContent); 38 39 if (!groupedCells[group]) { 40 groupedCells[group] = []; 41 } 42 43 groupedCells[group].push({ cell, value }); 44 }); 45 46 // Process each group independently 47 Object.keys(groupedCells).forEach(groupName => { 48 const cells = groupedCells[groupName]; 49 const maxValue = Math.max(...cells.map(c => c.value)); 50 51 if (maxValue === 0) return; 52 53 cells.forEach(({ cell, value }) => { 54 const percentage = (value / maxValue) * 100; 55 const minWidth = 18; 56 const finalWidth = Math.max(minWidth, percentage); 57 58 // Wrap text content in span if not already wrapped 59 if (!cell.querySelector('.b2g-spec-text')) { 60 const textContent = cell.innerHTML; 61 cell.innerHTML = `<span class="b2g-spec-text">${textContent}</span>`; 62 } 63 64 cell.style.setProperty('--bar-width', `${finalWidth}%`); 65 cell.classList.add('b2g-spec-dynamic'); 66 67 }); 68 }); 69 } 70 71 /** 72 * Process data bars by column (default, for standard tables) 73 */ 74 function processDataBarsByColumn(table) { 75 const rows = Array.from(table.querySelectorAll('tbody tr')); 76 if (rows.length === 0) return; 77 78 const firstRow = rows[0]; 79 const cellCount = firstRow.querySelectorAll('td').length; 80 81 // Process each column independently 82 for (let colIndex = 0; colIndex < cellCount; colIndex++) { 83 const columnCells = []; 84 85 rows.forEach(row => { 86 const cells = Array.from(row.querySelectorAll('td')); 87 const cell = cells[colIndex]; 88 89 if (cell && cell.hasAttribute('data-level')) { 90 const value = extractNumericValue(cell.textContent); 91 columnCells.push({ cell, value }); 92 } 93 }); 94 95 if (columnCells.length === 0) continue; 96 97 const maxValue = Math.max(...columnCells.map(c => c.value)); 98 if (maxValue === 0) continue; 99 100 columnCells.forEach(({ cell, value }) => { 101 const percentage = (value / maxValue) * 100; 102 const minWidth = 18; 103 const finalWidth = Math.max(minWidth, percentage); 104 105 // Wrap text content in span if not already wrapped 106 if (!cell.querySelector('.b2g-spec-text')) { 107 const textContent = cell.innerHTML; 108 cell.innerHTML = `<span class="b2g-spec-text">${textContent}</span>`; 109 } 110 111 cell.style.setProperty('--bar-width', `${finalWidth}%`); 112 cell.classList.add('b2g-spec-dynamic'); 113 114 }); 115 } 116 } 117 118 /** 119 * Main processing function 120 */ 121 function processDataBars() { 122 const tables = document.querySelectorAll('.b2g-spec-table'); 123
124 tables.forEach(table => { 125 // Check if any cells have data-group attribute 126 const hasGroups = table.querySelector('td[data-group]') !== null; 127 128 if (hasGroups) { 129 processDataBarsByGroup(table); 130 } else { 131 processDataBarsByColumn(table); 132 } 133 }); 134 } 135 136 /** 137 * Initialize when DOM is ready 138 */ 139 function init() { 140 if (document.readyState === 'loading') { 141 document.addEventListener('DOMContentLoaded', processDataBars); 142 } else { 143 processDataBars(); 144 } 145 } 146 147 init(); 148 149})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.