MediaWiki:Common.js: Difference between revisions
Jump to navigation
Jump to search
Common.js: bind swccg-card-link hover to existing card-zoom popup |
Common.js: clear #swccg-card-zoom src before load so Firefox never flashes previous card |
||
| Line 1: | Line 1: | ||
/* Logo stays in the sidebar. Search sits at the left of the header. | /* Logo stays in the sidebar. Search sits at the left of the header. | ||
Card list: 200px thumbs for load; hover shows a fixed popup of the full 745px GEMP image. | Card list: 200px thumbs for load; hover shows a fixed popup of the full 745px GEMP image. | ||
Chrome/Edge ignore src changes while srcset is set, so we never swap the thumb src. */ | Chrome/Edge ignore src changes while srcset is set, so we never swap the thumb src. | ||
CardLink / #swccg-card-zoom: clear src and hide until the new image loads so Firefox | |||
never flashes the previous card art. */ | |||
(function () { | (function () { | ||
function originalFromImg(img) { | function originalFromImg(img) { | ||
| Line 21: | Line 23: | ||
} | } | ||
function ensureZoomPop() { | |||
function | |||
var pop = document.getElementById('swccg-card-zoom'); | var pop = document.getElementById('swccg-card-zoom'); | ||
if (!pop) { | if (!pop) { | ||
| Line 30: | Line 31: | ||
document.body.appendChild(pop); | document.body.appendChild(pop); | ||
} | } | ||
return pop; | |||
} | |||
function placeZoom(pop, rect) { | |||
var w = 450; | |||
var h = 630; | |||
var left = rect.right + 10; | |||
if (left + w > window.innerWidth - 8) { | |||
left = Math.max(8, rect.left - w - 10); | |||
} | |||
var top = rect.top; | |||
if (top + h > window.innerHeight - 8) { | |||
top = Math.max(8, window.innerHeight - h - 8); | |||
} | |||
pop.style.left = left + 'px'; | |||
pop.style.top = top + 'px'; | |||
} | |||
/** Show full-size art without flashing the previously loaded card (Firefox). */ | |||
function showZoom(pop, full, rect) { | |||
if (!full) { | |||
return; | |||
} | |||
placeZoom(pop, rect); | |||
var cur = pop.getAttribute('src') || ''; | |||
if (cur === full && pop.complete && pop.naturalWidth > 0) { | |||
pop.classList.add('is-on'); | |||
return; | |||
} | |||
pop.classList.remove('is-on'); | |||
pop.removeAttribute('src'); | |||
var gen = (parseInt(pop.getAttribute('data-zoom-gen') || '0', 10) || 0) + 1; | |||
pop.setAttribute('data-zoom-gen', String(gen)); | |||
function reveal() { | |||
if (pop.getAttribute('data-zoom-gen') !== String(gen)) { | |||
return; | |||
} | |||
if (pop.naturalWidth > 0) { | |||
pop.classList.add('is-on'); | |||
} | |||
} | |||
pop.onload = reveal; | |||
pop.onerror = function () { | |||
if (pop.getAttribute('data-zoom-gen') === String(gen)) { | |||
pop.classList.remove('is-on'); | |||
} | |||
}; | |||
pop.src = full; | |||
if (pop.complete) { | |||
reveal(); | |||
} | |||
} | |||
function hideZoom(pop) { | |||
pop.classList.remove('is-on'); | |||
} | |||
function bindCardLinks(root) { | |||
var pop = ensureZoomPop(); | |||
var nodes = (root || document).querySelectorAll('span.swccg-card-link[data-card-image]'); | var nodes = (root || document).querySelectorAll('span.swccg-card-link[data-card-image]'); | ||
for (var i = 0; i < nodes.length; i++) { | for (var i = 0; i < nodes.length; i++) { | ||
| Line 38: | Line 98: | ||
(function (el) { | (function (el) { | ||
el.addEventListener('mouseenter', function () { | el.addEventListener('mouseenter', function () { | ||
showZoom(pop, el.getAttribute('data-card-image'), el.getBoundingClientRect()); | |||
}); | }); | ||
el.addEventListener('mouseleave', function () { | el.addEventListener('mouseleave', function () { | ||
pop | hideZoom(pop); | ||
}); | }); | ||
})(nodes[i]); | })(nodes[i]); | ||
| Line 66: | Line 108: | ||
function bindZoom(root) { | function bindZoom(root) { | ||
var pop = | var pop = ensureZoomPop(); | ||
var links = (root || document).querySelectorAll('table.card-thumbs a, .card-portrait a'); | var links = (root || document).querySelectorAll('table.card-thumbs a, .card-portrait a'); | ||
for (var i = 0; i < links.length; i++) { | for (var i = 0; i < links.length; i++) { | ||
| Line 85: | Line 121: | ||
} | } | ||
a.addEventListener('mouseenter', function () { | a.addEventListener('mouseenter', function () { | ||
showZoom(pop, originalFromImg(img), img.getBoundingClientRect()); | |||
}); | }); | ||
a.addEventListener('mouseleave', function () { | a.addEventListener('mouseleave', function () { | ||
pop | hideZoom(pop); | ||
}); | }); | ||
})(links[i]); | })(links[i]); | ||
Revision as of 00:37, 24 September 2026
/* Logo stays in the sidebar. Search sits at the left of the header.
Card list: 200px thumbs for load; hover shows a fixed popup of the full 745px GEMP image.
Chrome/Edge ignore src changes while srcset is set, so we never swap the thumb src.
CardLink / #swccg-card-zoom: clear src and hide until the new image loads so Firefox
never flashes the previous card art. */
(function () {
function originalFromImg(img) {
var src = img.getAttribute('src') || img.src || '';
var ss = img.getAttribute('srcset') || '';
var m = src.match(/\/images\/thumb\/([^/]+\/[^/]+\/[^/?#]+)\/\d+px-/);
if (m) {
return '/images/' + m[1];
}
m = ss.match(/\/images\/thumb\/([^/]+\/[^/]+\/[^/?#]+)\//);
if (m) {
return '/images/' + m[1];
}
m = src.match(/\/images\/[^/]+\/[^/]+\/Premiere-[LD]-[^/?#]+/i);
if (m) {
return m[0];
}
return src.split(' ')[0];
}
function ensureZoomPop() {
var pop = document.getElementById('swccg-card-zoom');
if (!pop) {
pop = document.createElement('img');
pop.id = 'swccg-card-zoom';
pop.alt = '';
document.body.appendChild(pop);
}
return pop;
}
function placeZoom(pop, rect) {
var w = 450;
var h = 630;
var left = rect.right + 10;
if (left + w > window.innerWidth - 8) {
left = Math.max(8, rect.left - w - 10);
}
var top = rect.top;
if (top + h > window.innerHeight - 8) {
top = Math.max(8, window.innerHeight - h - 8);
}
pop.style.left = left + 'px';
pop.style.top = top + 'px';
}
/** Show full-size art without flashing the previously loaded card (Firefox). */
function showZoom(pop, full, rect) {
if (!full) {
return;
}
placeZoom(pop, rect);
var cur = pop.getAttribute('src') || '';
if (cur === full && pop.complete && pop.naturalWidth > 0) {
pop.classList.add('is-on');
return;
}
pop.classList.remove('is-on');
pop.removeAttribute('src');
var gen = (parseInt(pop.getAttribute('data-zoom-gen') || '0', 10) || 0) + 1;
pop.setAttribute('data-zoom-gen', String(gen));
function reveal() {
if (pop.getAttribute('data-zoom-gen') !== String(gen)) {
return;
}
if (pop.naturalWidth > 0) {
pop.classList.add('is-on');
}
}
pop.onload = reveal;
pop.onerror = function () {
if (pop.getAttribute('data-zoom-gen') === String(gen)) {
pop.classList.remove('is-on');
}
};
pop.src = full;
if (pop.complete) {
reveal();
}
}
function hideZoom(pop) {
pop.classList.remove('is-on');
}
function bindCardLinks(root) {
var pop = ensureZoomPop();
var nodes = (root || document).querySelectorAll('span.swccg-card-link[data-card-image]');
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].getAttribute('data-zoom-bound')) {
continue;
}
nodes[i].setAttribute('data-zoom-bound', '1');
(function (el) {
el.addEventListener('mouseenter', function () {
showZoom(pop, el.getAttribute('data-card-image'), el.getBoundingClientRect());
});
el.addEventListener('mouseleave', function () {
hideZoom(pop);
});
})(nodes[i]);
}
}
function bindZoom(root) {
var pop = ensureZoomPop();
var links = (root || document).querySelectorAll('table.card-thumbs a, .card-portrait a');
for (var i = 0; i < links.length; i++) {
if (links[i].getAttribute('data-zoom-bound')) {
continue;
}
links[i].setAttribute('data-zoom-bound', '1');
(function (a) {
var img = a.querySelector('img');
if (!img) {
return;
}
a.addEventListener('mouseenter', function () {
showZoom(pop, originalFromImg(img), img.getBoundingClientRect());
});
a.addEventListener('mouseleave', function () {
hideZoom(pop);
});
})(links[i]);
}
}
function moveSearch() {
var search = document.getElementById('p-search');
var head = document.getElementById('mw-head');
if (search && head && search.parentNode !== head) {
head.insertBefore(search, head.firstChild);
}
}
function start() {
moveSearch();
bindZoom(document);
bindCardLinks(document);
}
if (window.mw && mw.hook) {
mw.hook('wikipage.content').add(function () {
start();
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', start);
} else {
start();
}
})();