Adds 'No Access' to Google search links if inaccessible
Від
// ==UserScript==
// @name Google search Link Checker
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Adds 'No Access' to Google search links if inaccessible
// @author Bui Quoc Dung
// @match https://www.google.com/search*
// @grant GM_xmlhttpRequest
// @connect *
// ==/UserScript==
(function () {
'use strict';
async function checkLinkStatus(url) {
return new Promise((resolve) => {
GM_xmlhttpRequest({
method: "HEAD",
url,
timeout: 5000,
onload: res => {
const ok = (res.status >= 200 && res.status < 400) || res.status === 0 || res.status === 403 || res.status === 405;
resolve(ok);
},
onerror: () => resolve(false),
ontimeout: () => resolve(false)
});
});
}
function addInaccessibleTag(link) {
if (!link || link.dataset.statusChecked) return;
link.dataset.statusChecked = 'true';
const url = link.href;
if (!url || url.startsWith('javascript:') || url.startsWith('#')) return;
checkLinkStatus(url).then(accessible => {
if (!accessible) {
if (link.querySelector('span.no-access-tag')) return;
const tag = document.createElement('span');
tag.textContent = ' No Access';
tag.className = 'no-access-tag';
tag.style.color = 'green';
tag.style.fontSize = '0.8em';
tag.style.marginLeft = '4px';
const h3 = link.querySelector('h3');
(h3 || link).appendChild(tag);
}
});
}
let scanTimeoutId = null;
function scanLinksDebounced() {
clearTimeout(scanTimeoutId);
scanTimeoutId = setTimeout(() => {
document.querySelectorAll('span.V9tjod a.zReHs').forEach(addInaccessibleTag);
document.querySelectorAll('div.g a:has(h3), div.MjjYud a:has(h3), div.hlcw0c a:has(h3)').forEach(addInaccessibleTag);
}, 300);
}
const observer = new MutationObserver(mutations => {
for (const m of mutations) {
for (const node of m.addedNodes) {
if (node.nodeType === 1 &&
(node.querySelector('span.V9tjod a.zReHs, div.g a:has(h3), div.MjjYud a:has(h3), div.hlcw0c a:has(h3)') ||
node.matches('.g, .MjjYud, .hlcw0c'))) {
scanLinksDebounced();
return;
}
}
}
});
const container = document.getElementById('center_col') || document.getElementById('rcnt') || document.body;
observer.observe(container, { childList: true, subtree: true });
if (document.readyState === 'loading') {
window.addEventListener('DOMContentLoaded', () => setTimeout(scanLinksDebounced, 1000));
} else {
setTimeout(scanLinksDebounced, 1000);
}
})();