The screenshots for plugins in the official WordPress repo, when clicked, load the full image in the same tab. We have to press browser’s back button (or use a keyboard shortcut) and do this for any other screenshots we want to view in full.
Here’s a userscript that fixes this in your browser. To use this, you need a Chrome extension like Tampermonkey. I use AdGuard Mac app for this.
// ==UserScript==
// @name WordPress Plugin Screenshots Lightbox (Image Gallery)
// @namespace http://tampermonkey.net/
// @version 2.0
// @description Lightbox for WordPress plugin image gallery screenshots
// @match *://wordpress.org/plugins/*
// @match *://*.wordpress.org/plugins/*
// @grant none
// @run-at document-end
// ==/UserScript==
(function() {
'use strict';
// Check if we're on a plugin page
if (!window.location.pathname.match(/\/plugins\/[^\/]+\/?$/)) {
return;
}
// Add styles
const style = document.createElement('style');
style.textContent = `
#wp-screenshot-lightbox {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.95);
z-index: 999999;
align-items: center;
justify-content: center;
}
#wp-screenshot-lightbox.active {
display: flex;
}
#wp-screenshot-lightbox img {
max-width: 90vw;
max-height: 90vh;
object-fit: contain;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
}
.wp-lightbox-close {
position: absolute;
top: 20px;
right: 30px;
font-size: 40px;
color: white;
cursor: pointer;
background: none;
border: none;
padding: 0;
width: 50px;
height: 50px;
display: flex;
align-items: center;
justify-content: center;
transition: opacity 0.2s;
}
.wp-lightbox-close:hover {
opacity: 0.7;
}
.wp-lightbox-nav {
position: absolute;
top: 50%;
transform: translateY(-50%);
font-size: 60px;
color: white;
cursor: pointer;
background: none;
border: none;
padding: 0 20px;
user-select: none;
transition: opacity 0.2s;
}
.wp-lightbox-nav:hover:not(:disabled) {
opacity: 0.7;
}
.wp-lightbox-nav:disabled {
opacity: 0.2;
cursor: not-allowed;
}
.wp-lightbox-prev {
left: 0;
}
.wp-lightbox-next {
right: 0;
}
.wp-lightbox-counter {
position: absolute;
bottom: 30px;
left: 50%;
transform: translateX(-50%);
color: white;
background: rgba(0, 0, 0, 0.7);
padding: 10px 20px;
border-radius: 5px;
font-size: 16px;
}
`;
document.head.appendChild(style);
// Create lightbox HTML
const lightbox = document.createElement('div');
lightbox.id = 'wp-screenshot-lightbox';
lightbox.innerHTML = `
<button class="wp-lightbox-close" aria-label="Close">×</button>
<button class="wp-lightbox-nav wp-lightbox-prev" aria-label="Previous">‹</button>
<img src="" alt="Screenshot" />
<button class="wp-lightbox-nav wp-lightbox-next" aria-label="Next">›</button>
<div class="wp-lightbox-counter"></div>
`;
document.body.appendChild(lightbox);
const img = lightbox.querySelector('img');
const closeBtn = lightbox.querySelector('.wp-lightbox-close');
const prevBtn = lightbox.querySelector('.wp-lightbox-prev');
const nextBtn = lightbox.querySelector('.wp-lightbox-next');
const counter = lightbox.querySelector('.wp-lightbox-counter');
let screenshots = [];
let currentIndex = 0;
function initLightbox() {
// Get the main gallery container
const gallery = document.querySelector('.image-gallery-slides');
if (!gallery) return;
// Find all screenshot links using event delegation
const screenshotLinks = gallery.querySelectorAll('.image-gallery-image a');
screenshots = Array.from(screenshotLinks).map(link => link.href);
if (screenshots.length === 0) return;
}
// Use event delegation on the gallery container
document.addEventListener('click', (e) => {
// Check if click is on an image gallery link or its child
const link = e.target.closest('.image-gallery-slide .image-gallery-image a');
if (!link) return;
e.preventDefault();
// Find which index this link corresponds to
const allLinks = document.querySelectorAll('.image-gallery-slide .image-gallery-image a');
screenshots = Array.from(allLinks).map(l => l.href);
currentIndex = Array.from(allLinks).indexOf(link);
if (currentIndex !== -1) {
showLightbox();
}
});
function showLightbox() {
img.src = screenshots[currentIndex];
lightbox.classList.add('active');
document.body.style.overflow = 'hidden';
updateUI();
}
function closeLightbox() {
lightbox.classList.remove('active');
document.body.style.overflow = '';
}
function updateUI() {
counter.textContent = `${currentIndex + 1} / ${screenshots.length}`;
prevBtn.disabled = currentIndex === 0;
nextBtn.disabled = currentIndex === screenshots.length - 1;
// Hide elements if only one image
if (screenshots.length === 1) {
counter.style.display = 'none';
prevBtn.style.display = 'none';
nextBtn.style.display = 'none';
} else {
counter.style.display = 'block';
prevBtn.style.display = 'flex';
nextBtn.style.display = 'flex';
}
}
function navigate(direction) {
const newIndex = currentIndex + direction;
if (newIndex >= 0 && newIndex < screenshots.length) {
currentIndex = newIndex;
img.src = screenshots[currentIndex];
updateUI();
}
}
// Event listeners
closeBtn.addEventListener('click', closeLightbox);
prevBtn.addEventListener('click', () => navigate(-1));
nextBtn.addEventListener('click', () => navigate(1));
// Close on overlay click
lightbox.addEventListener('click', (e) => {
if (e.target === lightbox) {
closeLightbox();
}
});
// Keyboard navigation
document.addEventListener('keydown', (e) => {
if (!lightbox.classList.contains('active')) return;
switch(e.key) {
case 'Escape':
closeLightbox();
break;
case 'ArrowLeft':
navigate(-1);
break;
case 'ArrowRight':
navigate(1);
break;
}
});
// Initialize
initLightbox();
})();