Last active
April 12, 2023 20:35
-
-
Save rynomad/fcdd150aed64ebfec98c284c753241ad to your computer and use it in GitHub Desktop.
drag and drop code blocks to merge them
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Draggable & Droppable Code Elements | |
// @namespace http://tampermonkey.net/ | |
// @version 0.2 | |
// @description Make code elements draggable, droppable, and merge their contents when dropped onto each other. | |
// @author You | |
// @match https://*/* | |
// @grant GM.addStyle | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
// Add CSS for visual indicators | |
GM.addStyle(` | |
.dragged { | |
opacity: 0.5; | |
} | |
.dragged-over { | |
border: 2px dashed #f1c40f; | |
} | |
.dropped { | |
border: 2px solid #e74c3c; | |
} | |
`); | |
function makeDraggableAndDroppable() { | |
const codeElements = document.querySelectorAll('code'); | |
for (const codeElement of codeElements) { | |
const parentDiv = codeElement.parentElement; | |
if (parentDiv && parentDiv.classList.contains('p-4') && parentDiv.classList.contains('overflow-y-auto')) { | |
parentDiv.setAttribute('draggable', 'true'); | |
if (!parentDiv.hasAttribute('data-dnd-initialized')) { | |
parentDiv.setAttribute('data-dnd-initialized', 'true'); | |
parentDiv.addEventListener('dragstart', (event) => { | |
event.stopPropagation(); | |
event.dataTransfer.setData('text/plain', codeElement.textContent); | |
event.dataTransfer.effectAllowed = 'move'; | |
parentDiv.classList.add('dragged'); | |
}); | |
parentDiv.addEventListener('dragend', () => { | |
parentDiv.classList.remove('dragged'); | |
}); | |
parentDiv.addEventListener('dragenter', (event) => { | |
event.stopPropagation(); | |
event.preventDefault(); | |
parentDiv.classList.add('dragged-over'); | |
}); | |
parentDiv.addEventListener('dragleave', () => { | |
parentDiv.classList.remove('dragged-over'); | |
}); | |
parentDiv.addEventListener('dragover', (event) => { | |
event.preventDefault(); | |
if (!parentDiv.classList.contains('dragged-over')) { | |
parentDiv.classList.add('dragged-over'); | |
} | |
}); | |
parentDiv.addEventListener('drop', (event) => { | |
event.stopPropagation(); | |
event.preventDefault(); | |
const draggedElementText = event.dataTransfer.getData('text/plain'); | |
const mergedText = mergeText(codeElement.textContent, draggedElementText); | |
codeElement.textContent = mergedText; | |
parentDiv.classList.remove('dragged-over'); | |
parentDiv.classList.add('dropped'); | |
setTimeout(() => { | |
parentDiv.classList.remove('dropped'); | |
}, 1000); | |
}); | |
} | |
} | |
} | |
} | |
function mergeText(text1, text2) { | |
// Remove whitespace from the beginning and end of the strings | |
const trimmedText1 = text1.trim(); | |
const trimmedText2 = text2.trim(); | |
for (let overlapLength = 200; overlapLength > 0; overlapLength--) { | |
if (trimmedText1.slice(-overlapLength) === trimmedText2.slice(0, overlapLength)) { | |
// Reconstruct the merged string using the original text1 and text2 | |
return trimmedText1 + trimmedText2.slice(overlapLength).trim(); | |
} | |
} | |
return text1 + text2; | |
} | |
const observer = new MutationObserver(makeDraggableAndDroppable); | |
observer.observe(document, { childList: true, subtree: true }); | |
makeDraggableAndDroppable(); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment