(refs)
| 84 | } |
| 85 | |
| 86 | function renderRefPanel(refs) { |
| 87 | clearOverlays(); |
| 88 | if (!refs || refs.length === 0) return; |
| 89 | |
| 90 | const container = ensureContainer(); |
| 91 | |
| 92 | const panel = document.createElement('div'); |
| 93 | panel.className = 'gstack-ref-panel'; |
| 94 | |
| 95 | const header = document.createElement('div'); |
| 96 | header.className = 'gstack-ref-panel-header'; |
| 97 | header.textContent = `gstack refs (${refs.length})`; |
| 98 | header.style.cssText = 'pointer-events: auto; cursor: move;'; |
| 99 | panel.appendChild(header); |
| 100 | |
| 101 | const list = document.createElement('div'); |
| 102 | list.className = 'gstack-ref-panel-list'; |
| 103 | for (const ref of refs.slice(0, 30)) { // Show max 30 in panel |
| 104 | const row = document.createElement('div'); |
| 105 | row.className = 'gstack-ref-panel-row'; |
| 106 | const idSpan = document.createElement('span'); |
| 107 | idSpan.className = 'gstack-ref-panel-id'; |
| 108 | idSpan.textContent = ref.ref; |
| 109 | const roleSpan = document.createElement('span'); |
| 110 | roleSpan.className = 'gstack-ref-panel-role'; |
| 111 | roleSpan.textContent = ref.role; |
| 112 | const nameSpan = document.createElement('span'); |
| 113 | nameSpan.className = 'gstack-ref-panel-name'; |
| 114 | nameSpan.textContent = '"' + ref.name + '"'; |
| 115 | row.append(idSpan, document.createTextNode(' '), roleSpan, document.createTextNode(' '), nameSpan); |
| 116 | list.appendChild(row); |
| 117 | } |
| 118 | if (refs.length > 30) { |
| 119 | const more = document.createElement('div'); |
| 120 | more.className = 'gstack-ref-panel-more'; |
| 121 | more.textContent = `+${refs.length - 30} more`; |
| 122 | list.appendChild(more); |
| 123 | } |
| 124 | panel.appendChild(list); |
| 125 | container.appendChild(panel); |
| 126 | } |
| 127 | |
| 128 | // ─── Basic Inspector Picker (CSP fallback) ────────────────── |
| 129 | // When inspector.js can't be injected (CSP, chrome:// pages), content.js |
no test coverage detected