130 lines
4.5 KiB
JavaScript
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.'
|
|
);
|
|
})();
|