Smart Copy Paste Application
';
const blob = new Blob([docxHeader + html + docxFooter], { type: 'application/msword;charset=utf-8' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `smart-notes-${Date.now()}.doc`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
showToast('Word-compatible document exported');
}function printDocument() {
const win = window.open('', '_blank');
if (!win) {
showToast('Popup blocked. Allow popups to print.', true);
return;
}
win.document.write(`
Print Notes${editor.innerHTML}`);
win.document.close();
win.focus();
setTimeout(() => { win.print(); win.close(); }, 300);
}// Formatting Helper using Saved Range
function applyFormat(command, value = null) {
saveStateToHistory();
restoreSelection();
if (command === 'formatBlock') {
document.execCommand('formatBlock', false, `<${value}>`);
} else {
document.execCommand(command, false, value);
}
state.lastRecordedHtml = editor.innerHTML;
updateUndoRedoButtons();
editor.focus();
}// Insert Table at Cursor
const tableModal = root.querySelector('#scpt-table-modal-overlay');
function openTableModal() {
saveSelection();
if (tableModal) tableModal.style.display = 'flex';
}function closeTableModal() {
if (tableModal) tableModal.style.display = 'none';
}function insertTableAtSelection() {
saveStateToHistory();
restoreSelection();
const rows = parseInt(root.querySelector('#scpt-table-rows').value) || 3;
const cols = parseInt(root.querySelector('#scpt-table-cols').value) || 3;let tableHtml = '
';
for (let c = 0; c < cols; c++) tableHtml += `| Header ${c + 1} | `;
tableHtml += '
';
for (let r = 0; r < rows - 1; r++) {
tableHtml += '';
for (let c = 0; c < cols; c++) tableHtml += `| Data ${r + 1},${c + 1} | `;
tableHtml += '
';
}
tableHtml += '
';const sel = window.getSelection();
if (sel && sel.rangeCount > 0 && editor.contains(sel.getRangeAt(0).commonAncestorContainer)) {
const range = sel.getRangeAt(0);
range.deleteContents();
const el = document.createElement('div');
el.innerHTML = tableHtml;
const frag = document.createDocumentFragment();
let lastNode;
while (el.firstChild) {
lastNode = frag.appendChild(el.firstChild);
}
range.insertNode(frag);
if (lastNode) {
range.setStartAfter(lastNode);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
} else {
editor.insertAdjacentHTML('beforeend', tableHtml);
}closeTableModal();
state.lastRecordedHtml = editor.innerHTML;
updateUndoRedoButtons();
showToast('Table inserted successfully');
}// Insert Diagram at Cursor
function insertDiagramAtSelection() {
saveStateToHistory();
restoreSelection();
const svgHtml = '
';
const sel = window.getSelection();
if (sel && sel.rangeCount > 0 && editor.contains(sel.getRangeAt(0).commonAncestorContainer)) {
const range = sel.getRangeAt(0);
range.deleteContents();
const el = document.createElement('div');
el.innerHTML = svgHtml;
const frag = document.createDocumentFragment();
let lastNode;
while (el.firstChild) {
lastNode = frag.appendChild(el.firstChild);
}
range.insertNode(frag);
if (lastNode) {
range.setStartAfter(lastNode);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
} else {
editor.insertAdjacentHTML('beforeend', svgHtml);
}state.lastRecordedHtml = editor.innerHTML;
updateUndoRedoButtons();
showToast('Diagram inserted successfully');
}// Paste AI Notes Modal workflow
const pasteModal = root.querySelector('#scpt-paste-modal-overlay');
const pasteTextarea = root.querySelector('#scpt-paste-textarea');async function openPasteModal() {
saveSelection();
if (pasteTextarea) pasteTextarea.value = '';
try {
if (navigator.clipboard && navigator.clipboard.readText) {
const text = await navigator.clipboard.readText();
if (text && pasteTextarea) {
pasteTextarea.value = text;
}
}
} catch (err) {
// Clipboard read permission denied or not supported; allow manual paste in textarea
}
if (pasteModal) pasteModal.style.display = 'flex';
if (pasteTextarea) pasteTextarea.focus();
}function closePasteModal() {
if (pasteModal) pasteModal.style.display = 'none';
}function confirmPasteModal() {
if (!pasteTextarea) return;
const content = pasteTextarea.value;
if (!content.trim()) {
showToast('Paste content is empty', true);
return;
}
saveStateToHistory();
restoreSelection();
const parsed = sanitizeAndParseHtml(content);const sel = window.getSelection();
if (sel && sel.rangeCount > 0 && editor.contains(sel.getRangeAt(0).commonAncestorContainer)) {
const range = sel.getRangeAt(0);
range.deleteContents();
const el = document.createElement('div');
el.innerHTML = parsed;
const frag = document.createDocumentFragment();
let lastNode;
while (el.firstChild) {
lastNode = frag.appendChild(el.firstChild);
}
range.insertNode(frag);
if (lastNode) {
range.setStartAfter(lastNode);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
} else {
editor.insertAdjacentHTML('beforeend', parsed);
}closePasteModal();
state.lastRecordedHtml = editor.innerHTML;
updateUndoRedoButtons();
showToast('AI notes parsed and inserted successfully');
}// Event Listeners Initialization
root.addEventListener('click', (e) => {
const diagNode = e.target.closest('.scpt-diagram-node');
const diagToolbar = root.querySelector('#scpt-diagram-toolbar');
root.querySelectorAll('.scpt-diagram-node').forEach(n => n.classList.remove('selected'));
if (diagNode) {
diagNode.classList.add('selected');
state.selectedDiagram = diagNode;
if (diagToolbar) diagToolbar.style.display = 'flex';
} else if (!e.target.closest('#scpt-diagram-toolbar')) {
state.selectedDiagram = null;
if (diagToolbar) diagToolbar.style.display = 'none';
}
});// Toolbar Buttons binding
root.querySelector('#scpt-smart-paste-btn').onclick = (e) => { e.preventDefault(); openPasteModal(); };
root.querySelector('#scpt-fix-symbols-btn').onclick = (e) => { e.preventDefault(); repairSymbolsInEditor(); };
root.querySelector('#scpt-doc-check-btn').onclick = (e) => { e.preventDefault(); runDocumentCheck(); };
root.querySelector('#scpt-undo-btn').onclick = (e) => { e.preventDefault(); executeUndo(); };
root.querySelector('#scpt-redo-btn').onclick = (e) => { e.preventDefault(); executeRedo(); };root.querySelector('#scpt-copy-full-btn').onclick = (e) => { e.preventDefault(); ClipboardManager.copyFull(); };
root.querySelector('#scpt-copy-word-btn').onclick = (e) => { e.preventDefault(); ClipboardManager.copyForWord(); };
root.querySelector('#scpt-copy-html-btn').onclick = (e) => { e.preventDefault(); ClipboardManager.copyHtml(); };
root.querySelector('#scpt-copy-plain-btn').onclick = (e) => { e.preventDefault(); ClipboardManager.copyPlainText(); };root.querySelector('#scpt-export-word-btn').onclick = (e) => { e.preventDefault(); exportWordDoc(); };
root.querySelector('#scpt-print-pdf-btn').onclick = (e) => { e.preventDefault(); printDocument(); };// Formatting buttons
root.querySelectorAll('.scpt-fmt-btn[data-cmd]').forEach(btn => {
btn.onclick = (e) => {
e.preventDefault();
applyFormat(btn.dataset.cmd, btn.dataset.value || null);
};
});root.querySelector('#scpt-insert-table-btn').onclick = (e) => { e.preventDefault(); openTableModal(); };
root.querySelector('#scpt-insert-svg-btn').onclick = (e) => { e.preventDefault(); insertDiagramAtSelection(); };// View mode toggles
root.querySelectorAll('.scpt-view-btn').forEach(btn => {
btn.onclick = (e) => {
e.preventDefault();
root.querySelectorAll('.scpt-view-btn').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
const view = btn.dataset.view;
if (view === 'editor') {
state.isViewMode = false;
editor.setAttribute('contenteditable', 'true');
showToast('Switched to Editor Mode');
} else if (view === 'preview') {
state.isViewMode = true;
editor.setAttribute('contenteditable', 'false');
showToast('Switched to Preview Mode');
} else if (view === 'print') {
printDocument();
}
};
});// Modals closing events
root.querySelector('#scpt-modal-close').onclick = (e) => { e.preventDefault(); root.querySelector('#scpt-modal-overlay').style.display = 'none'; };
root.querySelector('#scpt-modal-dismiss-btn').onclick = (e) => { e.preventDefault(); root.querySelector('#scpt-modal-overlay').style.display = 'none'; };root.querySelector('#scpt-table-modal-close').onclick = (e) => { e.preventDefault(); closeTableModal(); };
root.querySelector('#scpt-table-modal-dismiss').onclick = (e) => { e.preventDefault(); closeTableModal(); };
root.querySelector('#scpt-table-insert-confirm').onclick = (e) => { e.preventDefault(); insertTableAtSelection(); };root.querySelector('#scpt-paste-modal-close').onclick = (e) => { e.preventDefault(); closePasteModal(); };
root.querySelector('#scpt-paste-modal-dismiss').onclick = (e) => { e.preventDefault(); closePasteModal(); };
root.querySelector('#scpt-paste-insert-confirm').onclick = (e) => { e.preventDefault(); confirmPasteModal(); };// Diagram Actions
root.querySelectorAll('.scpt-diag-action').forEach(btn => {
btn.onclick = (e) => {
e.preventDefault();
if (!state.selectedDiagram) {
showToast('No diagram selected', true);
return;
}
const action = btn.dataset.action;
const svgEl = state.selectedDiagram.querySelector('svg');if (action === 'view' || action === 'center') {
state.selectedDiagram.scrollIntoView({ behavior: 'smooth', block: 'center' });
showToast(action === 'center' ? 'Diagram centered' : 'Viewing diagram');
} else if (action === 'copy') {
if (svgEl) {
navigator.clipboard.writeText(svgEl.outerHTML);
showToast('Diagram SVG copied to clipboard');
}
} else if (action === 'svg') {
if (svgEl) {
const blob = new Blob([svgEl.outerHTML], { type: 'image/svg+xml;charset=utf-8' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `diagram-${Date.now()}.svg`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
showToast('SVG downloaded successfully');
}
} else if (action === 'delete') {
saveStateToHistory();
state.selectedDiagram.remove();
state.selectedDiagram = null;
root.querySelector('#scpt-diagram-toolbar').style.display = 'none';
state.lastRecordedHtml = editor.innerHTML;
updateUndoRedoButtons();
showToast('Diagram deleted');
}
};
});// Editor input & mutation handling
let debounceTimer;
editor.addEventListener('input', () => {
if (state.isViewMode) return;
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => {
saveStateToHistory();
}, 500);
});editor.addEventListener('mouseup', saveSelection);
editor.addEventListener('keyup', saveSelection);// Keyboard shortcuts
editor.addEventListener('keydown', (e) => {
if ((e.ctrlKey || e.metaKey) && !e.shiftKey && e.key.toLowerCase() === 'z') {
e.preventDefault();
executeUndo();
} else if ((e.ctrlKey || e.metaKey) && (e.key.toLowerCase() === 'y' || (e.shiftKey && e.key.toLowerCase() === 'z'))) {
e.preventDefault();
executeRedo();
}
});// Initialize first history entry
state.history.push(editor.innerHTML);
state.lastRecordedHtml = editor.innerHTML;
updateUndoRedoButtons();
}if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initApp);
} else {
initApp();
}
})();