hover fix
This commit is contained in:
@@ -24,6 +24,8 @@
|
||||
const hasActiveProfile = !!window.PYTORRENT?.activeProfile;
|
||||
let firstRunSetupShown = false;
|
||||
const activeOperations = new Map();
|
||||
// Note: Keeps live filter tooltips stable while the pointer is over a filter button.
|
||||
const filterTooltipState = new WeakMap();
|
||||
|
||||
function toast(msg, type="secondary") { const h=$('toastHost'); if(!h) return; const el=document.createElement('div'); el.className=`toast-item text-bg-${type}`; el.innerHTML=esc(msg); h.appendChild(el); setTimeout(()=>el.remove(),3500); }
|
||||
function setBusy(on){ pendingBusy += on ? 1 : -1; if(pendingBusy<0) pendingBusy=0; $('globalLoader')?.classList.toggle('d-none', pendingBusy===0); $('busyBadge')?.classList.toggle('d-none', pendingBusy===0); }
|
||||
@@ -93,6 +95,41 @@
|
||||
}
|
||||
return lines.join('\n');
|
||||
}
|
||||
function applyFilterTooltip(button, tooltip, ariaLabel){
|
||||
if(tooltip){
|
||||
button.title = tooltip;
|
||||
button.setAttribute('aria-label', ariaLabel);
|
||||
} else {
|
||||
button.removeAttribute('title');
|
||||
button.removeAttribute('aria-label');
|
||||
}
|
||||
}
|
||||
function ensureStableFilterTooltip(button){
|
||||
if(filterTooltipState.has(button)) return filterTooltipState.get(button);
|
||||
const state = {hovering:false, pending:null};
|
||||
filterTooltipState.set(button, state);
|
||||
button.addEventListener('mouseenter', () => {
|
||||
state.hovering = true;
|
||||
state.pending = null;
|
||||
});
|
||||
button.addEventListener('mouseleave', () => {
|
||||
state.hovering = false;
|
||||
if(state.pending){
|
||||
applyFilterTooltip(button, state.pending.tooltip, state.pending.ariaLabel);
|
||||
state.pending = null;
|
||||
}
|
||||
});
|
||||
return state;
|
||||
}
|
||||
// Note: Freezes tooltip content during hover; the next hover receives the newest live summary.
|
||||
function setStableFilterTooltip(button, tooltip, ariaLabel){
|
||||
const state = ensureStableFilterTooltip(button);
|
||||
if(state.hovering){
|
||||
state.pending = {tooltip, ariaLabel};
|
||||
return;
|
||||
}
|
||||
applyFilterTooltip(button, tooltip, ariaLabel);
|
||||
}
|
||||
function setFilterSummary(type){
|
||||
const el=$(FILTER_COUNT_IDS[type]);
|
||||
if(!el) return;
|
||||
@@ -102,13 +139,8 @@
|
||||
el.innerHTML=`<span class="filter-count">${esc(bucket.count||0)}</span>${meta?`<span class="filter-meta">${esc(meta)}</span>`:''}`;
|
||||
const button=el.closest('.filter');
|
||||
if(button){
|
||||
if(tooltip){
|
||||
button.title=tooltip;
|
||||
button.setAttribute('aria-label', `${button.dataset.filter || type}: ${tooltip.replace(/\n/g, ', ')}`);
|
||||
} else {
|
||||
button.removeAttribute('title');
|
||||
button.removeAttribute('aria-label');
|
||||
}
|
||||
const ariaLabel = tooltip ? `${button.dataset.filter || type}: ${tooltip.replace(/\n/g, ', ')}` : '';
|
||||
setStableFilterTooltip(button, tooltip, ariaLabel);
|
||||
}
|
||||
}
|
||||
function labelNames(value){ return String(value||'').split(/[,;|]+/).map(x=>x.trim()).filter(Boolean).filter((x,i,a)=>a.indexOf(x)===i); }
|
||||
|
||||
Reference in New Issue
Block a user