const inputText = document.getElementById('input-text'); const bubbleContainer = document.getElementById('bubble-container'); const replaceSpacesButton = document.getElementById('replace-spaces-button'); const replaceUnderscoreButton = document.getElementById('replace-underscore-button'); const revertUnderscoreButton = document.getElementById('revert-underscore-button'); const replaceLineBreaksButton = document.getElementById('replace-linebreaks-button'); const replaceCommasButton = document.getElementById('replace-commas-button'); const removeDuplicatesButton = document.getElementById('remove-duplicates-button'); const revertSpacesButton = document.getElementById('revert-spaces-button'); const copyButton = document.getElementById('copy-button'); const undoButton = document.getElementById('undo-button'); const redoButton = document.getElementById('redo-button'); const deleteModeButton = document.getElementById('delete-mode-button'); const emphasisModeButton = document.getElementById('emphasis-mode-button'); const mitigateModeButton = document.getElementById('mitigate-mode-button'); const bubbleColors = {}; let history = []; let historyIndex = -1; let deleteModeEnabled = false; let emphasisModeEnabled = false; let mitigateModeEnabled = false; inputText.addEventListener('input', handleTextChange); replaceSpacesButton.addEventListener('click', replaceSpaces); replaceUnderscoreButton.addEventListener('click', replaceUnderscores); revertUnderscoreButton.addEventListener('click', revertUnderscores); replaceLineBreaksButton.addEventListener('click', replaceLineBreaks); replaceCommasButton.addEventListener('click', replaceCommas); removeDuplicatesButton.addEventListener('click', removeDuplicates); revertSpacesButton.addEventListener('click', revertSpaces); copyButton.addEventListener('click', copyToClipboard); undoButton.addEventListener('click', undoChanges); redoButton.addEventListener('click', redoChanges); deleteModeButton.addEventListener('click', toggleDeleteMode); emphasisModeButton.addEventListener('click', toggleEmphasisMode); mitigateModeButton.addEventListener('click', toggleMitigateMode); const sortable = new Sortable(bubbleContainer, { animation: 250, ghostClass: 'ghost', onEnd: handleBubbleChange, disabled: deleteModeEnabled || emphasisModeEnabled || mitigateModeEnabled }); function handleTextChange() { const text = inputText.value; if (history.length === 0) { history.push(''); historyIndex++; } if (text !== history[historyIndex]) { if (historyIndex < history.length - 1) { history.splice(historyIndex + 1); } history.push(text); historyIndex++; updateBubbles(); updateButtonStates(); } } function handleBubbleChange() { const conceptList = Array.from(bubbleContainer.getElementsByClassName('bubble')).map(bubble => bubble.textContent.trim()); inputText.value = conceptList.join(', '); handleTextChange(); } function updateBubbles() { bubbleContainer.innerHTML = ''; const text = inputText.value.trim(); if (text === '') return; const concepts = text.split(', '); concepts.forEach(concept => { const bubble = createBubble(concept); bubbleContainer.appendChild(bubble); }); } function createBubble(text) { const bubble = document.createElement('div'); bubble.classList.add('bubble'); if (!bubbleColors.hasOwnProperty(text)) { bubbleColors[text] = getRandomColor(); } bubble.style.backgroundColor = bubbleColors[text]; const bubbleText = document.createElement('span'); bubbleText.classList.add('bubble-text'); bubbleText.innerText = text; bubble.appendChild(bubbleText); if (deleteModeEnabled) { bubble.classList.add('delete-mode'); bubble.addEventListener('click', deleteBubble); } if (emphasisModeEnabled) { bubble.classList.add('emphasis-mode'); bubble.addEventListener('click', emphasizeBubble); } if (mitigateModeEnabled) { bubble.classList.add('mitigate-mode'); bubble.addEventListener('click', mitigateBubble); } return bubble; } function getRandomColor() { const h = Math.floor(Math.random() * 360); const s = Math.floor(Math.random() * 30) + 50; const l = Math.floor(Math.random() * 40) + 30; return `hsl(${h}, ${s}%, ${l}%)`; } function updateButtonStates() { undoButton.disabled = historyIndex === 0; redoButton.disabled = historyIndex === history.length - 1; } function replaceSpaces() { const text = inputText.value; const replacedText = text.replace(/ /g, ', '); inputText.value = replacedText; handleTextChange(); } function revertSpaces() { const text = inputText.value; const replacedText = text.replace(/, /g, ' '); inputText.value = replacedText; handleTextChange(); } function replaceUnderscores() { const text = inputText.value; const replacedText = text.replace(/_/g, ' '); inputText.value = replacedText; handleTextChange(); } function revertUnderscores() { const text = inputText.value; const replacedText = text.replace(/([^,]) /g, '$1_'); inputText.value = replacedText; handleTextChange(); } function replaceLineBreaks() { const text = inputText.value; const replacedText = text.replace(/\n/g, ', '); inputText.value = replacedText; handleTextChange(); } function replaceCommas() { const text = inputText.value; const step1 = text.replace(/,,/g, ','); const step2 = step1.replace(/, ,/g, ', '); const step3 = step2.trimRight(); const step4 = step3.replace(/,$/, ''); const step5 = step4.replace(/^,/, ''); const step6 = step5.replace(/, /g, ', '); const replacedText = step6.replace(/^ /, ''); inputText.value = replacedText; handleTextChange(); } function removeDuplicates() { const text = inputText.value; const concepts = text.split(', '); const uniqueConcepts = [...new Set(concepts)]; inputText.value = uniqueConcepts.join(', '); handleTextChange(); } function copyToClipboard() { inputText.select(); inputText.setSelectionRange(0, 99999); document.execCommand('copy'); } function undoChanges() { if (historyIndex > 0) { historyIndex--; inputText.value = history[historyIndex]; updateBubbles(); updateButtonStates(); } } function redoChanges() { if (historyIndex < history.length - 1) { historyIndex++; inputText.value = history[historyIndex]; updateBubbles(); updateButtonStates(); } } function toggleDeleteMode() { deleteModeEnabled = !deleteModeEnabled; deleteModeButton.classList.toggle('active'); if (deleteModeEnabled) { emphasisModeEnabled = false; emphasisModeButton.classList.remove('active'); mitigateModeEnabled = false; mitigateModeButton.classList.remove('active'); } sortable.option('disabled', deleteModeEnabled); bubbleContainer.classList.toggle('delete-mode-container'); const bubbles = bubbleContainer.getElementsByClassName('bubble'); for (let i = 0; i < bubbles.length; i++) { const bubble = bubbles[i]; bubble.classList.remove('emphasis-mode'); bubble.classList.remove('mitigate-mode'); if (deleteModeEnabled) { bubble.classList.add('delete-mode'); bubble.removeEventListener('click', emphasizeBubble); bubble.removeEventListener('click', mitigateBubble); bubble.addEventListener('click', deleteBubble); } else { bubble.classList.remove('delete-mode'); bubble.removeEventListener('click', deleteBubble); } } } function toggleEmphasisMode() { emphasisModeEnabled = !emphasisModeEnabled; emphasisModeButton.classList.toggle('active'); if (emphasisModeEnabled) { deleteModeEnabled = false; deleteModeButton.classList.remove('active'); mitigateModeEnabled = false; mitigateModeButton.classList.remove('active'); } sortable.option('disabled', emphasisModeEnabled); bubbleContainer.classList.toggle('emphasis-mode-container'); const bubbles = bubbleContainer.getElementsByClassName('bubble'); for (let i = 0; i < bubbles.length; i++) { const bubble = bubbles[i]; bubble.classList.remove('delete-mode'); bubble.classList.remove('mitigate-mode'); if (emphasisModeEnabled) { bubble.classList.add('emphasis-mode'); bubble.removeEventListener('click', deleteBubble); bubble.removeEventListener('click', mitigateBubble); bubble.addEventListener('click', emphasizeBubble); } else { bubble.classList.remove('emphasis-mode'); bubble.removeEventListener('click', emphasizeBubble); } } } function toggleMitigateMode() { mitigateModeEnabled = !mitigateModeEnabled; mitigateModeButton.classList.toggle('active'); if (mitigateModeEnabled) { deleteModeEnabled = false; deleteModeButton.classList.remove('active'); emphasisModeEnabled = false; emphasisModeButton.classList.remove('active'); } sortable.option('disabled', mitigateModeEnabled); bubbleContainer.classList.toggle('mitigate-mode-container'); const bubbles = bubbleContainer.getElementsByClassName('bubble'); for (let i = 0; i < bubbles.length; i++) { const bubble = bubbles[i]; bubble.classList.remove('delete-mode'); bubble.classList.remove('emphasis-mode'); if (mitigateModeEnabled) { bubble.classList.add('mitigate-mode'); bubble.removeEventListener('click', deleteBubble); bubble.removeEventListener('click', emphasizeBubble); bubble.addEventListener('click', mitigateBubble); } else { bubble.classList.remove('mitigate-mode'); bubble.removeEventListener('click', mitigateBubble); } } } function deleteBubble(event) { const bubble = event.target.closest('.bubble'); const bubbleText = bubble.querySelector('.bubble-text'); const nextComma = bubbleText.nextSibling; bubble.remove(); if (nextComma && nextComma.nodeType === Node.TEXT_NODE && nextComma.textContent.trim() === ',') { nextComma.remove(); } handleBubbleChange(); } function emphasizeBubble(event) { const bubble = event.target.closest('.bubble'); const bubbleText = bubble.querySelector('.bubble-text'); const text = bubbleText.innerText.trim(); if (text.startsWith('[') && text.endsWith(']')) { bubbleText.innerText = text.slice(1, -1); } else { bubbleText.innerText = `(${text})`; } handleBubbleChange(); } function mitigateBubble(event) { const bubble = event.target.closest('.bubble'); const bubbleText = bubble.querySelector('.bubble-text'); const text = bubbleText.innerText.trim(); if (text.startsWith('(') && text.endsWith(')')) { bubbleText.innerText = text.slice(1, -1); } else { bubbleText.innerText = `[${text}]`; } handleBubbleChange(); }