Βελτιωμένη εξαγωγή direct URLs σε Google Images. Δουλεύει καλύτερα με hover/middle-click. Διατηρεί side preview στο left-click.
// ==UserScript==
// @name PAPAZ Google Direct Image Links (2026)
// @version 3.0
// @description Βελτιωμένη εξαγωγή direct URLs σε Google Images. Δουλεύει καλύτερα με hover/middle-click. Διατηρεί side preview στο left-click.
// @author DoctorEye
// @namespace DoctorEye
// @match https://www.google.com/search?*
// @match https://www.google.gr/search?*
// @match https://www.google.com/*/search?*
// @match https://www.google.gr/*/search?*
// @match https://images.google.com/*
// @match https://images.google.gr/*
// @grant none
// @license Proprietary
// @run-at document-end
// ==/UserScript==
(function() {
'use strict';
// Βοηθητική: βρίσκει το πιθανότερο direct URL από το link ή τα παιδιά του
function extractDirectUrl(element) {
if (!element) return null;
const candidates = [];
// 1. Κλασικό imgurl (παλιό αλλά ακόμα σε μερικά)
let href = element.href || '';
if (href.includes('/imgres?')) {
try {
const params = new URLSearchParams(new URL(href, location.origin).search);
if (params.has('imgurl')) candidates.push(decodeURIComponent(params.get('imgurl')));
} catch {}
}
// 2. Data attributes (συχνά κρυμμένα JSON ή encoded URLs)
['data-afm', 'data-ved', 'jsdata', 'data-ou', 'data-original', 'data-src-full', 'data-lt'].forEach(attr => {
const val = element.getAttribute(attr);
if (val) {
// Αναζήτηση URL pattern
const match = val.match(/(https?:\/\/[^"'<>\s)]+\.(jpe?g|png|webp|gif|bmp|svg)(?::[^"'<>\s)]*)?)/gi);
if (match) candidates.push(...match);
// Προσπάθεια decode base64 αν είναι encoded
try {
const decoded = atob(val.replace(/[^A-Za-z0-9+/=]/g, ''));
const subMatch = decoded.match(/(https?:\/\/[^"'<>\s)]+\.(jpe?g|png|webp|gif|bmp|svg)(?::[^"'<>\s)]*)?)/gi);
if (subMatch) candidates.push(...subMatch);
} catch {}
}
});
// 3. Το img src/data-src (μετά hover συνήθως γίνεται μεγαλύτερο)
const img = element.querySelector('img');
if (img) {
['src', 'data-src', 'data-lt-src'].forEach(key => {
let s = img.getAttribute(key);
if (s && s.startsWith('https://') && !s.includes('googleusercontent.com') && s.length > 200) {
candidates.push(s.split('?')[0]); // καθαρό URL χωρίς params μεγέθους
}
});
}
// Επιστροφή του μεγαλύτερου/καθαρότερου candidate (συνήθως το καλύτερο είναι το πιο μακρύ)
if (candidates.length === 0) return null;
return candidates.sort((a,b) => b.length - a.length)[0] || null;
}
function processElement(el) {
if (el.dataset.directFixed === 'yes') return;
const url = extractDirectUrl(el);
if (url) {
el.href = url;
el.dataset.directFixed = 'yes';
// Προαιρετικό tooltip
el.title = (el.title || '') + ' → Direct: ' + url.split('/').pop();
console.log('[DirectFix] Applied:', url);
}
}
// Βρες όλα τα πιθανά links εικόνων (ευρύ φάσμα selectors)
function scanPage() {
const selectors = [
'a[jsname][role="link"]',
'a[href*="/imgres"]',
'a[aria-label*="Image result"]',
'div[data-id] > a',
'.wXeWr a', '.iPVvYb a', '.islrc a', '.rg_i a', // συχνές κλάσεις
'div[role="listitem"] a',
'a > div > img' // parent του img
].join(', ');
document.querySelectorAll(selectors).forEach(el => {
let link = el.closest('a') || el;
if (link && link.tagName === 'A') processElement(link);
});
}
// Αρχική εκτέλεση
window.addEventListener('load', scanPage);
setTimeout(scanPage, 1500); // extra για late loads
// MutationObserver → νέα αποτελέσματα από scroll
new MutationObserver(muts => {
if (muts.some(m => m.addedNodes.length > 0)) {
setTimeout(scanPage, 400);
}
}).observe(document.body, { childList: true, subtree: true });
// Κρίσιμο: hover & focus → Google φορτώνει data εκεί
['mouseover', 'focusin'].forEach(ev => {
document.addEventListener(ev, e => {
let link = e.target.closest('a');
if (link) {
setTimeout(() => processElement(link), 250); // δίνουμε χρόνο στο Google JS
}
}, true);
});
// Periodic refresh (κάθε ~4 δευτ. για safety)
setInterval(scanPage, 4000);
// Bonus: Middle-click override (προαιρετικό – ανοίγει direct χωρίς side panel αν θες)
// Αφαίρεσε τα σχόλια αν το θες ενεργό
/*
document.addEventListener('auxclick', e => {
if (e.button === 1) { // middle click
let link = e.target.closest('a');
if (link && link.dataset.directFixed === 'yes') {
e.preventDefault();
e.stopPropagation();
window.open(link.href, '_blank');
}
}
}, true);
*/
})();