Files

130 lines
4.5 KiB
JavaScript

/**
* Bookmarklet script for extracting and copying place IDs from map links.
*
* - Attaches a click handler to the document that intercepts clicks on <a> tags containing a MapIcon SVG.
* - When such a link is clicked, prevents navigation and copies the place ID (from the URL) to the clipboard.
* - Displays a modal notification in the top-right corner for feedback (success/failure).
* - After copying, attempts to open the MoreVertIcon menu and highlights the "hide" menu item for user convenience.
* - Ensures only links not labeled "close popup" are intercepted.
* - Provides a cleanup function to remove event handlers and modals when re-activated or unloaded.
* - Shows an activation modal when the bookmarklet is run.
*
* Usage: Run as a bookmarklet on pages with map links to quickly copy place IDs.
*/
(function () {
// Cleanup previous handlers and modals if present
if (window.__bmCleanup) {
window.__bmCleanup();
}
// Show a modal in the top right for feedback
function showModal(msg) {
var modal = document.createElement('div');
modal.id = '__bmModal';
modal.textContent = msg;
modal.style.position = 'fixed';
modal.style.top = '20px';
modal.style.right = '20px';
modal.style.background = '#222';
modal.style.color = '#fff';
modal.style.padding = '12px 24px';
modal.style.borderRadius = '8px';
modal.style.zIndex = '9999';
modal.style.fontSize = '16px';
modal.style.boxShadow = '0 2px 8px rgba(0,0,0,0.2)';
document.body.appendChild(modal);
window.__bmModalTimeout = setTimeout(function () {
if (modal.parentNode) modal.parentNode.removeChild(modal);
}, 5000);
}
// Copy text to clipboard (Safari compatible)
function copyToClipboard(text) {
var textarea = document.createElement('textarea');
textarea.value = text;
textarea.style.position = 'fixed';
document.body.appendChild(textarea);
textarea.focus();
textarea.select();
try {
document.execCommand('copy');
showModal('Copied: ' + text);
} catch (e) {
showModal('Failed to copy: ' + text);
}
document.body.removeChild(textarea);
}
// After copying, open MoreVertIcon menu and highlight "hide" item
function moreVertAndHighlightHide() {
var buttons = document.querySelectorAll('button');
buttons.forEach(function (btn) {
var svg = btn.querySelector('svg[data-testid="MoreVertIcon"]');
if (svg) {
btn.click();
setTimeout(function () {
var lis = document.querySelectorAll('li');
for (var i = 0; i < lis.length; i++) {
var li = lis[i];
if (
li.className &&
li.className.indexOf('MuiMenuItem') !== -1 &&
/hide/i.test(li.textContent)
) {
li.style.background = 'yellow';
li.focus();
break;
}
}
}, 500);
}
});
}
// Main click handler for <a> tags with MapIcon
function handler(e) {
var aTag = e.target.closest('a');
if (aTag) {
var ariaLabel = aTag.getAttribute('aria-label');
// Only block navigation if aria-label does not contain "close popup"
if (!ariaLabel || ariaLabel.toLowerCase().indexOf('close popup') === -1) {
e.preventDefault();
e.stopPropagation();
var svgs = aTag.querySelectorAll('svg[data-testid="MapIcon"]');
if (svgs.length) {
if (aTag.href) {
var parts = aTag.href.split('place/');
var placeId = parts[1];
if (placeId) {
copyToClipboard(placeId);
setTimeout(moreVertAndHighlightHide, 100);
} else {
showModal('No place/ found in URL');
}
} else {
showModal('No href found on <a>');
}
}
}
}
}
// Add the click handler
document.addEventListener('click', handler, true);
// Cleanup function to remove handlers and modals
window.__bmCleanup = function () {
document.removeEventListener('click', handler, true);
var modal = document.getElementById('__bmModal');
if (modal && modal.parentNode) modal.parentNode.removeChild(modal);
if (window.__bmModalTimeout) clearTimeout(window.__bmModalTimeout);
delete window.__bmCleanup;
delete window.__bmModalTimeout;
};
// Show activation modal
showModal(
'Bookmarklet active! All links are disabled except "close popup". Click a link containing a MapIcon to copy its place ID.'
);
})();