fix(popup): replace innerHTML with DOM API to fix Firefox warnings

Firefox flagged unsafe innerHTML assignments:
- renderEmpty() container.innerHTML with template literal
- renderOnboardingStep() dots.innerHTML with mapped content
- updateLastActionUI() lastActionCard.innerHTML static string
- refreshRooms click handler publicRooms.innerHTML

Replaced all with createElement + textContent/replaceChildren.
This commit is contained in:
Koala
2026-05-25 12:52:32 +02:00
parent 807a620fe9
commit 94fab41ab5
+31 -12
View File
@@ -171,7 +171,11 @@ function updateUI(roomId, password, useCustomServer = false, serverUrl = '') {
function updateLastActionUI(state, peers) { function updateLastActionUI(state, peers) {
if (!state || !state.action) { if (!state || !state.action) {
elements.lastActionCard.innerHTML = '<div style="text-align:center; color: var(--text-muted); font-size: 10px;">No recent commands</div>'; elements.lastActionCard.replaceChildren();
const el = document.createElement('div');
el.style.cssText = 'text-align:center; color: var(--text-muted); font-size: 10px;';
el.textContent = 'No recent commands';
elements.lastActionCard.appendChild(el);
return; return;
} }
@@ -304,13 +308,21 @@ function renderEmpty(container, type) {
rooms: { icon: '\u{1F50D}', title: 'No active rooms', hint: 'Create a room or refresh to find public ones' } rooms: { icon: '\u{1F50D}', title: 'No active rooms', hint: 'Create a room or refresh to find public ones' }
}; };
const state = states[type] || { icon: '', title: '', hint: '' }; const state = states[type] || { icon: '', title: '', hint: '' };
container.innerHTML = ` const wrapper = document.createElement('div');
<div style="text-align:center; padding:16px 8px; color:var(--text-muted);"> wrapper.style.cssText = 'text-align:center; padding:16px 8px; color:var(--text-muted);';
<div style="font-size:24px; margin-bottom:6px;">${state.icon}</div> const iconDiv = document.createElement('div');
<div style="font-size:12px; font-weight:600; margin-bottom:4px;">${state.title}</div> iconDiv.style.cssText = 'font-size:24px; margin-bottom:6px;';
<div style="font-size:10px; opacity:0.7;">${state.hint}</div> iconDiv.textContent = state.icon;
</div> const titleDiv = document.createElement('div');
`; titleDiv.style.cssText = 'font-size:12px; font-weight:600; margin-bottom:4px;';
titleDiv.textContent = state.title;
const hintDiv = document.createElement('div');
hintDiv.style.cssText = 'font-size:10px; opacity:0.7;';
hintDiv.textContent = state.hint;
wrapper.appendChild(iconDiv);
wrapper.appendChild(titleDiv);
wrapper.appendChild(hintDiv);
container.replaceChildren(wrapper);
} }
function updatePeerList(peers) { function updatePeerList(peers) {
@@ -925,7 +937,11 @@ elements.createRoomBtn.addEventListener('click', () => {
}); });
elements.refreshRooms.addEventListener('click', () => { elements.refreshRooms.addEventListener('click', () => {
elements.publicRooms.innerHTML = '<div style="text-align:center; padding: 10px; color:var(--text-muted);">Refreshing...</div>'; elements.publicRooms.replaceChildren();
const el = document.createElement('div');
el.style.cssText = 'text-align:center; padding: 10px; color:var(--text-muted);';
el.textContent = 'Refreshing...';
elements.publicRooms.appendChild(el);
chrome.runtime.sendMessage({ type: 'GET_ROOM_LIST' }); chrome.runtime.sendMessage({ type: 'GET_ROOM_LIST' });
}); });
@@ -1344,9 +1360,12 @@ function renderOnboardingStep() {
title.textContent = step.title; title.textContent = step.title;
text.textContent = step.text; text.textContent = step.text;
dots.innerHTML = onboardingSteps.map((_, i) => dots.replaceChildren();
`<div style="width:8px; height:8px; border-radius:50%; background:${i === onboardingStep ? 'var(--accent)' : '#475569'};"></div>` onboardingSteps.forEach((_, i) => {
).join(''); const dot = document.createElement('div');
dot.style.cssText = `width:8px; height:8px; border-radius:50%; background:${i === onboardingStep ? 'var(--accent)' : '#475569'};`;
dots.appendChild(dot);
});
nextBtn.textContent = onboardingStep === onboardingSteps.length - 1 ? 'Done!' : 'Next'; nextBtn.textContent = onboardingStep === onboardingSteps.length - 1 ? 'Done!' : 'Next';
} }