fix(popup): keep the room tab from stretching the popup

Chrome sizes the popup window to whatever the content claims it needs and
never shrinks that window back for the rest of the session. The clipping
rule that keeps content inside the fixed 360px body used a child
combinator for the room tab (#section-active > .info-card), which misses
#peerList -- it sits in a wrapper div. The sync tab's identical peer list
was covered by #tab-sync .info-card, so the room tab held the only
unclipped card in the popup: one overflowing peer row there left the
popup stuck at up to double width, including after switching back to
Sync.

Generalize the rule to .info-card so every card clips (cards that scroll
keep their own overflow-y), let the peer row's badge group wrap instead
of overflowing now that it would otherwise be cut off, wrap long room ids
and connection status text, and let the label/button rows in Sync and
Status wrap -- those were the next candidates with longer translations.

Verified against the built extension: no element in any tab can grow the
popup any more, in all 15 shipped locales.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Timo
2026-08-15 11:54:49 +02:00
parent 2fe785af6e
commit 381c6a93a2
2 changed files with 22 additions and 14 deletions
+17 -12
View File
@@ -1297,9 +1297,14 @@
.settings-issue-link a:hover { .settings-issue-link a:hover {
color: var(--accent); color: var(--accent);
} }
#section-join > .info-card, /* Every card clips horizontally. The popup body is a fixed 360px, but
#section-active > .info-card, Chrome sizes the popup window to whatever the content claims it needs
#tab-sync .info-card { — and it never shrinks that window back for the rest of the session.
So a single unclipped card (the room tab's peer list used to be one,
because it sits in a wrapper div and the child combinator missed it)
is enough to leave the popup stuck at double width. Cards that scroll
vertically keep their own overflow-y via inline styles. */
.info-card {
position: relative; position: relative;
overflow: hidden; overflow: hidden;
} }
@@ -1462,9 +1467,9 @@
<!-- ACTIVE SECTION: Visible when in a room --> <!-- ACTIVE SECTION: Visible when in a room -->
<div id="section-active" style="display:none;"> <div id="section-active" style="display:none;">
<div class="info-card" style="margin-bottom: 20px; display: flex; justify-content: space-between; align-items: center; border-left: 4px solid var(--accent);"> <div class="info-card" style="margin-bottom: 20px; display: flex; justify-content: space-between; align-items: center; border-left: 4px solid var(--accent);">
<div> <div style="min-width: 0;">
<label style="margin-bottom: 0;" title="The room you are currently connected to" data-i18n="LABEL_ACTIVE_ROOM" data-i18n-title="LABEL_ACTIVE_ROOM_TOOLTIP">Active Room</label> <label style="margin-bottom: 0;" title="The room you are currently connected to" data-i18n="LABEL_ACTIVE_ROOM" data-i18n-title="LABEL_ACTIVE_ROOM_TOOLTIP">Active Room</label>
<div id="activeRoomId" style="font-weight: 700; color: var(--accent); font-size: 16px; letter-spacing: 1px;">NONE</div> <div id="activeRoomId" style="font-weight: 700; color: var(--accent); font-size: 16px; letter-spacing: 1px; overflow-wrap: anywhere;">NONE</div>
</div> </div>
<div id="activeServer" style="font-size: 10px; color: var(--text-muted); text-align: right; max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">Official Server</div> <div id="activeServer" style="font-size: 10px; color: var(--text-muted); text-align: right; max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">Official Server</div>
</div> </div>
@@ -1524,8 +1529,8 @@
</div> </div>
</div> </div>
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px;"> <div style="display: flex; flex-wrap: wrap; gap: 6px; justify-content: space-between; align-items: center; margin-bottom: 4px;">
<label style="margin: 0;" data-i18n="LABEL_REMOTE_CONTROL">Remote Control</label> <label style="margin: 0; min-width: 0;" data-i18n="LABEL_REMOTE_CONTROL">Remote Control</label>
<button id="syncTabCopyInvite" title="Copy Invite Link" style="background:transparent; border: 1px solid var(--border-strong); border-radius: 6px; padding: 4px 8px; font-size: 11px; cursor:pointer; opacity:0.8; transition: opacity 0.2s; color: var(--text-muted); display: flex; align-items: center; gap: 4px; white-space: nowrap;" data-i18n="BTN_COPY_INVITE" data-i18n-title="BTN_COPY_INVITE_TOOLTIP">📋 Invite Link</button> <button id="syncTabCopyInvite" title="Copy Invite Link" style="background:transparent; border: 1px solid var(--border-strong); border-radius: 6px; padding: 4px 8px; font-size: 11px; cursor:pointer; opacity:0.8; transition: opacity 0.2s; color: var(--text-muted); display: flex; align-items: center; gap: 4px; white-space: nowrap;" data-i18n="BTN_COPY_INVITE" data-i18n-title="BTN_COPY_INVITE_TOOLTIP">📋 Invite Link</button>
</div> </div>
<div class="transport-actions"> <div class="transport-actions">
@@ -1813,7 +1818,7 @@
<div id="connStatus" class="info-card" style="display:flex; align-items:center; gap: 10px;"> <div id="connStatus" class="info-card" style="display:flex; align-items:center; gap: 10px;">
<span id="connDot" class="status-dot status-offline"></span> <span id="connDot" class="status-dot status-offline"></span>
<span style="flex:1; display:flex; align-items:center; gap:6px; min-width:0;"> <span style="flex:1; display:flex; align-items:center; gap:6px; min-width:0;">
<span id="connText">Disconnected</span> <span id="connText" style="overflow-wrap: anywhere;">Disconnected</span>
<span id="connInfo" data-i18n-title="STATUS_IDLE_TOOLTIP" title="KoalaSync is ready. Join or create a room to connect and start syncing." style="display:none; cursor:help; flex:none; width:15px; height:15px; line-height:14px; text-align:center; border-radius:50%; border:1px solid var(--text-muted); color:var(--text-muted); font-size:10px; font-weight:700; font-style:normal;">i</span> <span id="connInfo" data-i18n-title="STATUS_IDLE_TOOLTIP" title="KoalaSync is ready. Join or create a room to connect and start syncing." style="display:none; cursor:help; flex:none; width:15px; height:15px; line-height:14px; text-align:center; border-radius:50%; border:1px solid var(--text-muted); color:var(--text-muted); font-size:10px; font-weight:700; font-style:normal;">i</span>
</span> </span>
<span id="connPing" class="conn-ping"></span> <span id="connPing" class="conn-ping"></span>
@@ -1826,15 +1831,15 @@
<span data-i18n="VIDEO_DEBUG_EMPTY">No tab selected or video detected.</span> <span data-i18n="VIDEO_DEBUG_EMPTY">No tab selected or video detected.</span>
</div> </div>
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom: 8px;"> <div style="display:flex; flex-wrap:wrap; gap:6px; justify-content:space-between; align-items:center; margin-bottom: 8px;">
<label title="Chronological log of all sync commands in the room" data-i18n="LABEL_HISTORY" data-i18n-title="LABEL_HISTORY_TOOLTIP">Full Action History</label> <label style="min-width: 0;" title="Chronological log of all sync commands in the room" data-i18n="LABEL_HISTORY" data-i18n-title="LABEL_HISTORY_TOOLTIP">Full Action History</label>
</div> </div>
<div id="historyList" class="info-card" style="max-height: 120px; overflow-y: auto; font-size: 10px; margin-bottom: 15px;"> <div id="historyList" class="info-card" style="max-height: 120px; overflow-y: auto; font-size: 10px; margin-bottom: 15px;">
<div style="text-align:center; color: var(--text-muted); font-size: 11px;" data-i18n="HISTORY_EMPTY">No activity yet</div> <div style="text-align:center; color: var(--text-muted); font-size: 11px;" data-i18n="HISTORY_EMPTY">No activity yet</div>
</div> </div>
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom: 8px;"> <div style="display:flex; flex-wrap:wrap; gap:6px; justify-content:space-between; align-items:center; margin-bottom: 8px;">
<label title="Technical connection logs for debugging" data-i18n="LABEL_LOGS" data-i18n-title="LABEL_LOGS_TOOLTIP">Logs (Last 50)</label> <label style="min-width: 0;" title="Technical connection logs for debugging" data-i18n="LABEL_LOGS" data-i18n-title="LABEL_LOGS_TOOLTIP">Logs (Last 50)</label>
<button id="clearLogs" style="background:transparent; border:none; color:var(--accent); font-size:10px; cursor:pointer;" title="Clear log output" data-i18n="BTN_CLEAR" data-i18n-title="BTN_CLEAR_TOOLTIP">CLEAR</button> <button id="clearLogs" style="background:transparent; border:none; color:var(--accent); font-size:10px; cursor:pointer;" title="Clear log output" data-i18n="BTN_CLEAR" data-i18n-title="BTN_CLEAR_TOOLTIP">CLEAR</button>
</div> </div>
<div id="logList"></div> <div id="logList"></div>
+5 -2
View File
@@ -958,7 +958,7 @@ function updatePeerList(peers) {
peerItem.style.cssText = 'position:relative; display:block; padding: 8px 0; border-bottom: 1px solid var(--border-soft);'; peerItem.style.cssText = 'position:relative; display:block; padding: 8px 0; border-bottom: 1px solid var(--border-soft);';
const header = document.createElement('div'); const header = document.createElement('div');
header.style.cssText = 'display:flex; justify-content:space-between; align-items:center; padding-right: 24px;'; header.style.cssText = 'display:flex; justify-content:space-between; align-items:center; gap:6px; padding-right: 24px;';
const nameSpan = document.createElement('span'); const nameSpan = document.createElement('span');
nameSpan.style.cssText = 'display: inline-flex; align-items: center; max-width: 200px; overflow: hidden; white-space: nowrap;'; nameSpan.style.cssText = 'display: inline-flex; align-items: center; max-width: 200px; overflow: hidden; white-space: nowrap;';
@@ -982,8 +982,11 @@ function updatePeerList(peers) {
// Right-side badges + actions, kept in one group so they sit together // Right-side badges + actions, kept in one group so they sit together
// on the right instead of being scattered by the header's space-between. // on the right instead of being scattered by the header's space-between.
// They wrap onto a second line when the row runs out of room — badges
// and the co-host button are nowrap, so without this a busy row (Solo +
// role badge + "give control") would push past the card instead.
const rightGroup = document.createElement('div'); const rightGroup = document.createElement('div');
rightGroup.style.cssText = 'display:flex; align-items:center; gap:6px; flex-shrink:0;'; rightGroup.style.cssText = 'display:flex; align-items:center; justify-content:flex-end; flex-wrap:wrap; gap:6px; min-width:0;';
// Volume Icon (Top Right) // Volume Icon (Top Right)
if (p.volume !== undefined && p.volume !== null) { if (p.volume !== undefined && p.volume !== null) {