|
javascript:(function(){ |
|
const STORAGE_KEY = 'linkHighlighter_' + location.href; |
|
const highlighted = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]'); |
|
|
|
const colors = ['#1565C0','#D32F2F','#7B1FA2','#388E3C','#827717','#5E35B1','#303F9F','#880E4F','#00695C','#FF6F00','#795548','#9E9E9E','#0097A7','#607D8B']; |
|
let colorIndex = 0; |
|
const urlColorMap = {}; |
|
|
|
function getColorForUrl(url) { |
|
if (!urlColorMap[url]) { |
|
urlColorMap[url] = colors[colorIndex % colors.length]; |
|
colorIndex++; |
|
} |
|
return urlColorMap[url]; |
|
} |
|
|
|
function toggleHighlight(url, icon) { |
|
const allLinks = document.querySelectorAll('a[href]'); |
|
const matchingLinks = []; |
|
allLinks.forEach(link => { |
|
const rawHref = link.getAttribute('href'); |
|
if (cleanUrl(rawHref) === url) { |
|
matchingLinks.push(link); |
|
} |
|
}); |
|
|
|
const isHighlighted = highlighted.includes(url); |
|
|
|
if (isHighlighted) { |
|
const index = highlighted.indexOf(url); |
|
highlighted.splice(index, 1); |
|
matchingLinks.forEach(link => { |
|
link.style.backgroundColor = ''; |
|
link.style.border = ''; |
|
link.style.borderRadius = ''; |
|
link.style.padding = ''; |
|
}); |
|
icon.style.opacity = '0.3'; |
|
document.querySelectorAll('span[data-link-url="' + url + '"]').forEach(ic => { |
|
ic.style.color = '#ccc'; |
|
ic.style.opacity = '0.3'; |
|
}); |
|
} else { |
|
highlighted.push(url); |
|
const color = getColorForUrl(url); |
|
const lightColor = color + '33'; |
|
matchingLinks.forEach(link => { |
|
link.style.backgroundColor = lightColor; |
|
link.style.border = '2px solid ' + color; |
|
link.style.borderRadius = '4px'; |
|
link.style.padding = '2px 4px'; |
|
link.style.transition = 'all 0.3s'; |
|
}); |
|
icon.style.color = color; |
|
icon.style.opacity = '0.7'; |
|
document.querySelectorAll('span[data-link-url="' + url + '"]').forEach(ic => { |
|
ic.style.color = color; |
|
ic.style.opacity = '0.7'; |
|
}); |
|
} |
|
|
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(highlighted)); |
|
} |
|
|
|
function cleanUrl(url) { |
|
try { |
|
const u = new URL(url, location.href); |
|
return u.origin + u.pathname + u.search; |
|
} catch(e) { |
|
return url.split('#')[0]; |
|
} |
|
} |
|
|
|
const links = document.querySelectorAll('a[href]'); |
|
const processedUrls = new Set(); |
|
|
|
links.forEach(link => { |
|
const rawUrl = link.getAttribute('href'); |
|
if (!rawUrl || rawUrl.startsWith('#') || rawUrl.startsWith('javascript:')) return; |
|
const url = cleanUrl(rawUrl); |
|
|
|
const icon = document.createElement('span'); |
|
icon.innerHTML = '●'; |
|
icon.style.cssText = 'cursor:pointer;margin-right:5px;font-size:12px;user-select:none;display:inline-block;width:12px;text-align:center;'; |
|
icon.style.color = processedUrls.has(url) ? getColorForUrl(url) : '#ccc'; |
|
icon.style.opacity = highlighted.includes(url) ? '0.7' : '0.3'; |
|
icon.title = 'Highlight all links: ' + url; |
|
icon.setAttribute('data-link-url', url); |
|
|
|
icon.onclick = function(e) { |
|
e.preventDefault(); |
|
e.stopPropagation(); |
|
toggleHighlight(url, icon); |
|
}; |
|
|
|
link.parentNode.insertBefore(icon, link); |
|
processedUrls.add(url); |
|
|
|
}); |
|
|
|
highlighted.forEach(url => { |
|
const color = getColorForUrl(url); |
|
const lightColor = color + '33'; |
|
document.querySelectorAll('a[href]').forEach(link => { |
|
if (cleanUrl(link.getAttribute('href')) === url) { |
|
link.style.backgroundColor = lightColor; |
|
link.style.border = '2px solid ' + color; |
|
link.style.borderRadius = '4px'; |
|
link.style.padding = '2px 4px'; |
|
link.style.transition = 'all 0.3s'; |
|
} |
|
}); |
|
document.querySelectorAll('span[data-link-url="' + url + '"]').forEach(icon => { |
|
icon.style.color = color; |
|
icon.style.opacity = '0.7'; |
|
}); |
|
}); |
|
|
|
console.log('Link Highlighter: ' + processedUrls.size + ' unique links found, ' + highlighted.length + ' highlighted.'); |
|
})(); |