mirror of
https://github.com/mwisnowski/mtg_python_deckbuilder.git
synced 2025-12-16 07:30:13 +01:00
refactor(web): remove legacy card hover system (~230 lines of dead code)
This commit is contained in:
parent
6a94b982cb
commit
ed381dfdce
1 changed files with 5 additions and 160 deletions
|
|
@ -6,10 +6,6 @@
|
|||
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests" />
|
||||
<title>MTG Deckbuilder</title>
|
||||
<script src="https://unpkg.com/htmx.org@1.9.12" onerror="var s=document.createElement('script');s.src='/static/vendor/htmx-1.9.12.min.js';document.head.appendChild(s);"></script>
|
||||
<script>
|
||||
// Ensure legacy hover system never initializes (set before its script executes)
|
||||
window.__disableLegacyCardHover = true;
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
// Pre-CSS theme bootstrapping to avoid flash/mismatch on first paint
|
||||
|
|
@ -244,34 +240,7 @@
|
|||
setInterval(pollStatus, 10000);
|
||||
pollStatus();
|
||||
|
||||
function ensureCard() {
|
||||
// Legacy large image hover kept for fallback; disabled in favor of unified hover-card-panel
|
||||
if (window.__disableLegacyCardHover) return document.getElementById('card-hover') || document.createElement('div');
|
||||
var pop = document.getElementById('card-hover');
|
||||
if (!pop) {
|
||||
pop = document.createElement('div');
|
||||
pop.id = 'card-hover';
|
||||
pop.className = 'card-hover';
|
||||
var inner = document.createElement('div');
|
||||
inner.className = 'card-hover-inner';
|
||||
var img = document.createElement('img');
|
||||
img.alt = 'Card preview';
|
||||
var img2 = document.createElement('img');
|
||||
img2.alt = 'Card preview'; img2.style.display = 'none';
|
||||
var meta = document.createElement('div');
|
||||
meta.className = 'card-meta';
|
||||
var dual = document.createElement('div');
|
||||
dual.className = 'dual';
|
||||
dual.appendChild(img);
|
||||
dual.appendChild(img2);
|
||||
inner.appendChild(dual);
|
||||
inner.appendChild(meta);
|
||||
pop.appendChild(inner);
|
||||
document.body.appendChild(pop);
|
||||
}
|
||||
return pop;
|
||||
}
|
||||
var cardPop = ensureCard();
|
||||
// Card image URL builder with synergy annotation stripping
|
||||
var PREVIEW_VERSIONS = ['normal','large'];
|
||||
function normalizeCardName(raw){
|
||||
if(!raw) return raw;
|
||||
|
|
@ -340,132 +309,10 @@
|
|||
});
|
||||
}
|
||||
|
||||
function positionCard(e) {
|
||||
var x = e.clientX + 16, y = e.clientY + 16;
|
||||
cardPop.style.display = 'block';
|
||||
cardPop.style.left = x + 'px';
|
||||
cardPop.style.top = y + 'px';
|
||||
var rect = cardPop.getBoundingClientRect();
|
||||
var vw = window.innerWidth || document.documentElement.clientWidth;
|
||||
var vh = window.innerHeight || document.documentElement.clientHeight;
|
||||
if (x + rect.width + 8 > vw) cardPop.style.left = (e.clientX - rect.width - 16) + 'px';
|
||||
if (y + rect.height + 8 > vh) cardPop.style.top = (e.clientY - rect.height - 16) + 'px';
|
||||
}
|
||||
function attachCardHover() {
|
||||
if (window.__disableLegacyCardHover) return; // short-circuit legacy system
|
||||
document.querySelectorAll('[data-card-name]').forEach(function(el) {
|
||||
if (el.__cardHoverBound) return; // avoid duplicate bindings
|
||||
el.__cardHoverBound = true;
|
||||
el.addEventListener('mouseenter', function(e) {
|
||||
var img = cardPop.querySelector('.card-hover-inner img');
|
||||
var img2 = cardPop.querySelector('.card-hover-inner .dual img:nth-child(2)');
|
||||
if (img2) img2.style.display = 'none';
|
||||
var dualNode = cardPop.querySelector('.card-hover-inner .dual');
|
||||
if (img2) { img2.style.display = 'none'; }
|
||||
if (dualNode) { dualNode.classList.remove('combo','two-faced'); }
|
||||
var meta = cardPop.querySelector('.card-meta');
|
||||
var name = el.getAttribute('data-card-name') || '';
|
||||
var vi = 0; // always start at 'normal' on hover
|
||||
img.src = buildCardUrl(name, PREVIEW_VERSIONS[vi], false, 'front');
|
||||
// Bind a one-off error handler per enter to try fallbacks
|
||||
var triedNoCache = false;
|
||||
function onErr(){
|
||||
if (vi < PREVIEW_VERSIONS.length - 1){ vi += 1; img.src = buildCardUrl(name, PREVIEW_VERSIONS[vi], false, 'front'); }
|
||||
else if (!triedNoCache){ triedNoCache = true; img.src = buildCardUrl(name, PREVIEW_VERSIONS[vi], true, 'front'); }
|
||||
else { img.removeEventListener('error', onErr); }
|
||||
}
|
||||
img.addEventListener('error', onErr, { once:false });
|
||||
img.addEventListener('load', function onOk(){ img.removeEventListener('load', onOk); img.removeEventListener('error', onErr); });
|
||||
|
||||
// Attempt to load back face (double-faced / transform). If it fails, we silently hide.
|
||||
if (img2) {
|
||||
img2.style.display = 'none';
|
||||
var backTriedNoCache = false;
|
||||
var backIdx = 0;
|
||||
function backErr(){
|
||||
if (backIdx < PREVIEW_VERSIONS.length - 1){
|
||||
backIdx += 1; img2.src = buildCardUrl(name, PREVIEW_VERSIONS[backIdx], false, 'back');
|
||||
} else if (!backTriedNoCache){
|
||||
backTriedNoCache = true; img2.src = buildCardUrl(name, PREVIEW_VERSIONS[backIdx], true, 'back');
|
||||
} else {
|
||||
img2.removeEventListener('error', backErr); img2.style.display='none';
|
||||
}
|
||||
}
|
||||
function backOk(){ img2.removeEventListener('error', backErr); img2.removeEventListener('load', backOk); if (dualNode) dualNode.classList.add('two-faced'); img2.style.display=''; }
|
||||
img2.addEventListener('error', backErr, { once:false });
|
||||
img2.addEventListener('load', backOk, { once:false });
|
||||
img2.src = buildCardUrl(name, PREVIEW_VERSIONS[0], false, 'back');
|
||||
}
|
||||
var role = el.getAttribute('data-role') || '';
|
||||
var rawTags = el.getAttribute('data-tags') || '';
|
||||
var overlapsRaw = el.getAttribute('data-overlaps') || '';
|
||||
// Clean and split tags into an array; remove brackets and quotes
|
||||
var tags = rawTags
|
||||
.replace(/[\[\]\u2018\u2019'\u201C\u201D"]/g,'')
|
||||
.split(/\s*,\s*/)
|
||||
.filter(function(t){ return t && t.trim(); });
|
||||
var overlaps = overlapsRaw.split(/\s*,\s*/).filter(function(t){ return t; });
|
||||
var overlapSet = new Set(overlaps);
|
||||
var highlightOverlapsInList = overlaps.length === 0;
|
||||
if (role || (tags && tags.length)) {
|
||||
var html = '';
|
||||
if (role) {
|
||||
html += '<div class="line"><span class="label">Role</span>' + role.replace(/</g,'<') + '</div>';
|
||||
}
|
||||
if (tags && tags.length) {
|
||||
html += '<div class="line"><span class="label themes-label">Themes</span><ul class="themes-list">' + tags.map(function(t){ var safe=t.replace(/</g,'<'); var isOverlap = overlapSet.has(t); return '<li' + ((highlightOverlapsInList && isOverlap) ? ' class="overlap"' : '') + '>' + safe + '</li>'; }).join('') + '</ul></div>';
|
||||
if (overlaps.length){
|
||||
html += '<div class="line" style="margin-top:4px;"><span class="label" title="Themes shared with preview selection">Overlaps</span>' + overlaps.map(function(o){ return '<span class="ov-chip">'+o.replace(/</g,'<')+'</span>'; }).join(' ') + '</div>';
|
||||
}
|
||||
}
|
||||
meta.innerHTML = html;
|
||||
meta.style.display = '';
|
||||
} else {
|
||||
meta.style.display = 'none';
|
||||
meta.innerHTML = '';
|
||||
}
|
||||
positionCard(e);
|
||||
});
|
||||
el.addEventListener('mousemove', positionCard);
|
||||
el.addEventListener('mouseleave', function() { cardPop.style.display = 'none'; });
|
||||
});
|
||||
// Dual-card hover for combo rows
|
||||
document.querySelectorAll('[data-combo-names]').forEach(function(el){
|
||||
if (el.__comboHoverBound) return; el.__comboHoverBound = true;
|
||||
el.addEventListener('mouseenter', function(e){
|
||||
var namesAttr = el.getAttribute('data-combo-names') || '';
|
||||
var parts = namesAttr.split('||');
|
||||
var a = (parts[0]||'').trim(); var b = (parts[1]||'').trim();
|
||||
if (!a || !b) return;
|
||||
var img = cardPop.querySelector('.card-hover-inner img');
|
||||
var img2 = cardPop.querySelector('.card-hover-inner .dual img:nth-child(2)');
|
||||
var meta = cardPop.querySelector('.card-meta');
|
||||
if (img2) img2.style.display = '';
|
||||
var vi1 = 0, vi2 = 0; var triedNoCache1 = false, triedNoCache2 = false;
|
||||
img.src = buildCardUrl(a, PREVIEW_VERSIONS[vi1], false);
|
||||
img.src = buildCardUrl(a, PREVIEW_VERSIONS[vi1], false, 'front');
|
||||
img2.src = buildCardUrl(b, PREVIEW_VERSIONS[vi2], false, 'front');
|
||||
var dualNode = cardPop.querySelector('.card-hover-inner .dual');
|
||||
if (dualNode){ dualNode.classList.add('combo'); dualNode.classList.remove('two-faced'); }
|
||||
function err1(){ if (vi1 < PREVIEW_VERSIONS.length - 1){ vi1 += 1; img.src = buildCardUrl(a, PREVIEW_VERSIONS[vi1], false);} else if (!triedNoCache1){ triedNoCache1 = true; img.src = buildCardUrl(a, PREVIEW_VERSIONS[vi1], true);} else { img.removeEventListener('error', err1);} }
|
||||
function err2(){ if (vi2 < PREVIEW_VERSIONS.length - 1){ vi2 += 1; img2.src = buildCardUrl(b, PREVIEW_VERSIONS[vi2], false);} else if (!triedNoCache2){ triedNoCache2 = true; img2.src = buildCardUrl(b, PREVIEW_VERSIONS[vi2], true);} else { img2.removeEventListener('error', err2);} }
|
||||
img.addEventListener('error', err1, { once:false });
|
||||
img2.addEventListener('error', err2, { once:false });
|
||||
img.addEventListener('load', function on1(){ img.removeEventListener('load', on1); img.removeEventListener('error', err1); });
|
||||
img2.addEventListener('load', function on2(){ img2.removeEventListener('load', on2); img2.removeEventListener('error', err2); });
|
||||
meta.style.display = 'none'; meta.innerHTML = '';
|
||||
positionCard(e);
|
||||
});
|
||||
el.addEventListener('mousemove', positionCard);
|
||||
el.addEventListener('mouseleave', function(){ cardPop.style.display='none'; });
|
||||
});
|
||||
}
|
||||
// Expose re-init functions globally for dynamic content
|
||||
window.attachCardHover = attachCardHover;
|
||||
window.bindAllCardImageRetries = bindAllCardImageRetries;
|
||||
attachCardHover();
|
||||
bindAllCardImageRetries();
|
||||
document.addEventListener('htmx:afterSwap', function() { attachCardHover(); bindAllCardImageRetries(); });
|
||||
// Expose image retry binding globally for dynamic content
|
||||
window.bindAllCardImageRetries = bindAllCardImageRetries;
|
||||
bindAllCardImageRetries();
|
||||
document.addEventListener('htmx:afterSwap', bindAllCardImageRetries);
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
|
|
@ -765,8 +612,6 @@
|
|||
<script>
|
||||
// Global delegated hover card panel initializer (ensures functionality after HTMX swaps)
|
||||
(function(){
|
||||
// Disable legacy multi-element hover in favor of single unified panel
|
||||
window.__disableLegacyCardHover = true;
|
||||
// Global delegated curated-only & reasons controls (works after HTMX swaps and inline render)
|
||||
function findPreviewRoot(el){ return el.closest('.preview-modal-content.theme-preview-expanded') || el.closest('.preview-modal-content'); }
|
||||
function applyCuratedFor(root){
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue