✨ Add initial implementation and configuration files for Discord bot and dashboard
This commit is contained in:
129
code/utils/iplateau/coords-bookmarklet.js
Normal file
129
code/utils/iplateau/coords-bookmarklet.js
Normal file
@@ -0,0 +1,129 @@
|
||||
/**
|
||||
* 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.'
|
||||
);
|
||||
})();
|
||||
Reference in New Issue
Block a user