Smart AI Copy Paste

AI Notes Smart Copy

AI Notes Smart Copy

Client-side intelligent note cleaner, formatter, and multi-format exporter.

New

Formatted Preview

Your formatted notes preview will appear here…
Words: 0
Characters: 0
Chars (no spaces): 0
Lines: 0
Paragraphs: 0
Reading Time: 0 min
AI Notes Smart Copy © 2026. Fully Client-Side & Secure.
`; }, json: (title, content) => { detectStructure(); return JSON.stringify({ title: title, content: state.content, formattedContent: content, format: state.mode, structure: state.structure, updatedAt: new Date().toISOString() }, null, 2); }, csv: (title, content) => { const escapeCSV = (str) => `"${String(str || '').replace(/"/g, '""')}"`; let rows = [`"Type","Title","Content"`]; rows.push(`"Note",${escapeCSV(title)},${escapeCSV(content)}`); return rows.join('\r\n'); }, rtf: (title, content) => { const escapeRTF = (str) => String(str || '').replace(/[\\]/g, '\\\\').replace(/[{}]/g, '\\$&').replace(/\n/g, '\\par '); return `{\\rtf1\\ansi\\deff0 {\\fonttbl {\\f0 Helvetica;}} \\f0\\fs28 \\b ${escapeRTF(title)}\\b0\\par\\par \\fs20 ${escapeRTF(content)}}`; } };// Save Note Functionality function saveNote() { if (!state.content.trim() && !state.title.trim()) { showToast('Please enter some notes before saving.', 'error'); return; }const notes = loadNotesFromStorage(); const now = new Date().toISOString();if (!state.currentNoteId) { state.currentNoteId = generateUUID(); }const currentFormatted = getCurrentExportText(); detectStructure();const existingNote = notes[state.currentNoteId] || {};notes[state.currentNoteId] = { id: state.currentNoteId, title: state.title.trim() || 'Untitled Notes', content: state.content, formattedContent: currentFormatted, mode: state.mode, exportFormat: state.exportFormat, structure: state.structure, createdAt: existingNote.createdAt || now, updatedAt: now };if (saveNotesToStorage(notes)) { state.dirty = false; updateSaveState('Saved'); showToast('Note saved successfully!'); try { localStorage.removeItem(DRAFT_KEY); } catch (e) {} if (recentModal && recentModal.classList.contains('active')) { openRecentModal(); } } }// Open Recent Modal & Render List function openRecentModal() { try { const notes = loadNotesFromStorage(); const keys = Object.keys(notes); if (recentList) { recentList.innerHTML = ''; if (keys.length === 0) { recentList.innerHTML = '

No saved notes yet.

'; } else { keys.sort((a, b) => new Date(notes[b].updatedAt || 0) - new Date(notes[a].updatedAt || 0)).forEach(id => { const note = notes[id]; const item = document.createElement('div'); item.style.cssText = 'display: flex; justify-content: space-between; align-items: center; padding: 12px; border: 1px solid var(--border-color); border-radius: 6px; background: var(--bg-secondary); gap: 10px;'; const info = document.createElement('div'); info.style.cssText = 'flex: 1; min-width: 0;'; const titleSpan = document.createElement('strong'); titleSpan.textContent = note.title || 'Untitled'; titleSpan.style.cssText = 'display: block; font-size: 0.95rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;'; const previewSnippet = document.createElement('div'); previewSnippet.textContent = (note.content || '').substring(0, 80) + '...'; previewSnippet.style.cssText = 'font-size: 0.8rem; color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 2px;';const subInfo = document.createElement('div'); subInfo.style.cssText = 'font-size: 0.75rem; color: var(--text-secondary); margin-top: 4px;'; subInfo.textContent = new Date(note.updatedAt).toLocaleString(); info.appendChild(titleSpan); info.appendChild(previewSnippet); info.appendChild(subInfo);const actions = document.createElement('div'); actions.style.cssText = 'display: flex; gap: 6px; flex-shrink: 0;';const openBtn = document.createElement('button'); openBtn.className = 'ansc-btn ansc-btn-primary'; openBtn.textContent = 'Open'; openBtn.type = 'button'; openBtn.setAttribute('aria-label', `Open note ${note.title || 'Untitled'}`); openBtn.dataset.noteId = note.id; openBtn.addEventListener('click', () => { state.currentNoteId = note.id; state.title = note.title || 'Untitled Notes'; if (titleInputEl) titleInputEl.value = state.title; state.mode = note.mode || 'study'; if (formatStyleSelect) formatStyleSelect.value = state.mode; state.exportFormat = note.exportFormat || 'txt'; if (exportFormatSelect) exportFormatSelect.value = state.exportFormat; state.formattedContent = note.formattedContent || ''; state.formattedStale = false; state.structure = note.structure || state.structure;state.history = [note.content || '']; state.historyIndex = 0; updateUndoRedoButtons();setContentCore(note.content || ''); updateStats(note.content || ''); renderPreview(); state.dirty = false; updateSaveState('Saved'); closeModal(recentModal); performSearch(); showToast('Note opened.'); });const delBtn = document.createElement('button'); delBtn.className = 'ansc-btn ansc-btn-danger'; delBtn.textContent = 'Delete'; delBtn.type = 'button'; delBtn.setAttribute('aria-label', `Delete note ${note.title || 'Untitled'}`); delBtn.addEventListener('click', (e) => { e.stopPropagation(); if (confirm('Delete this note?')) { const freshNotes = loadNotesFromStorage(); delete freshNotes[note.id]; if (saveNotesToStorage(freshNotes)) { if (state.currentNoteId === note.id) { state.currentNoteId = null; } openRecentModal(); showToast('Note deleted.'); } } });actions.appendChild(openBtn); actions.appendChild(delBtn); item.appendChild(info); item.appendChild(actions); recentList.appendChild(item); }); } } openModal(recentModal, recentCloseBtn); } catch (e) { showToast('Failed to load recent notes.', 'error'); } }// Fallback Copy Function function fallbackCopy(text, callback) { try { const textArea = document.createElement("textarea"); textArea.value = text; textArea.style.position = "fixed"; textArea.style.top = "0"; textArea.style.left = "0"; textArea.style.opacity = "0"; document.body.appendChild(textArea); textArea.focus(); textArea.select(); const successful = document.execCommand('copy'); document.body.removeChild(textArea); callback(successful); } catch (err) { callback(false); } }// Event Listeners for UI Actions if (copyBtn) { copyBtn.addEventListener('click', () => { const textToCopy = getCurrentExportText(); if (!textToCopy.trim()) { showToast('Please enter or paste some notes first.', 'error'); return; }const cleanText = textToCopy.replace(/#{1,6}\s/g, '').replace(/[>*_]/g, '');if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(cleanText).then(() => { const orig = copyBtn.textContent; copyBtn.textContent = 'āœ“ Copied'; setTimeout(() => copyBtn.textContent = orig, 1500); showToast('Copied to clipboard successfully!'); }).catch(() => { fallbackCopy(cleanText, (success) => { if (success) { const orig = copyBtn.textContent; copyBtn.textContent = 'āœ“ Copied'; setTimeout(() => copyBtn.textContent = orig, 1500); showToast('Copied to clipboard successfully!'); } else { showToast('Clipboard access unavailable. Please copy manually.', 'error'); } }); }); } else { fallbackCopy(cleanText, (success) => { if (success) { const orig = copyBtn.textContent; copyBtn.textContent = 'āœ“ Copied'; setTimeout(() => copyBtn.textContent = orig, 1500); showToast('Copied to clipboard successfully!'); } else { showToast('Clipboard access unavailable. Please copy manually.', 'error'); } }); } }); }if (exportFormatSelect) { exportFormatSelect.addEventListener('change', (e) => { state.exportFormat = e.target.value; state.dirty = true; scheduleDraftAutosave(); }); }if (downloadBtn) { downloadBtn.addEventListener('click', () => { if (!state.content || !state.content.trim()) { showToast('Please enter or paste some notes first.', 'error'); return; }try { const content = getCurrentExportText(); const exporter = exporters[state.exportFormat] || exporters.txt; const fileContent = exporter(state.title, content);const mimeMap = { txt: 'text/plain', md: 'text/markdown', html: 'text/html', json: 'application/json', csv: 'text/csv', rtf: 'application/rtf' }; const mime = mimeMap[state.exportFormat] || 'text/plain';const blob = new Blob([fileContent], { type: `${mime};charset=utf-8` }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `${sanitizeFilename(state.title)}.${state.exportFormat}`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url);showToast('Downloaded successfully.'); } catch (e) { showToast('Unable to export this file. Please try again.', 'error'); } }); }if (detectBtn) { detectBtn.addEventListener('click', () => { if (!state.content || !state.content.trim()) { showToast('Please enter or paste some notes first.', 'error'); return; } const struct = detectStructure(); if (struct) { const totalHeadings = struct.headings.length + struct.subheadings.length; showToast(`Structure detected: ${totalHeadings} headings, ${struct.paragraphs.length} paragraphs, ${struct.bullets.length} bullets, ${struct.questions.length} questions.`, 'success'); } }); }if (formatBtn) { formatBtn.addEventListener('click', () => { if (!state.content || !state.content.trim()) { showToast('Please enter or paste some notes first.', 'error'); return; } try { detectStructure(); const formatter = formatters[state.mode] || formatters.study; state.formattedContent = formatter(state.content); state.formattedStale = false; renderPreview(); showToast('Notes formatted successfully!'); scheduleDraftAutosave(); } catch (e) { showToast('Unable to format these notes. Please try again.', 'error'); } }); }if (formatStyleSelect) { formatStyleSelect.addEventListener('change', (e) => { state.mode = e.target.value; state.formattedStale = true; state.dirty = true; scheduleDraftAutosave(); }); }if (editorEl) { editorEl.addEventListener('input', (e) => { setContent(e.target.value); }); }if (titleInputEl) { titleInputEl.addEventListener('input', (e) => { state.title = e.target.value.trim() || 'Untitled Notes'; state.dirty = true; updateSaveState('Unsaved changes'); scheduleDraftAutosave(); }); }if (clearBtn) { clearBtn.addEventListener('click', () => { if (state.content.trim() && confirm('Are you sure you want to clear the editor?')) { setContent(''); showToast('Editor cleared.'); } }); }if (newBtn) { newBtn.addEventListener('click', () => { if (state.dirty && state.content.trim()) { if (!confirm('You have unsaved changes. Create a new document anyway?')) return; } resetDocument(); showToast('New document created.'); }); }// Theme & Print & Paste bindings if (themeBtn) themeBtn.addEventListener('click', toggleTheme); if (printBtn) { printBtn.addEventListener('click', () => { if (!state.content || !state.content.trim()) { showToast('Please enter or paste some notes first.', 'error'); return; } try { window.print(); } catch (e) { showToast('Unable to print notes.', 'error'); } }); }if (pasteBtn) { pasteBtn.addEventListener('click', () => { if (modalPasteInput) modalPasteInput.value = ''; openModal(pasteModal, modalPasteInput); }); }if (modalCancelBtn && pasteModal) { modalCancelBtn.addEventListener('click', () => closeModal(pasteModal)); }if (modalInsertBtn && pasteModal && modalPasteInput) { modalInsertBtn.addEventListener('click', () => { const pastedText = modalPasteInput.value.trim(); if (!pastedText) { showToast('Please enter or paste text to insert.', 'error'); return; } const separator = state.content.trim() ? '\n\n' : ''; setContent(state.content + separator + pastedText); closeModal(pasteModal); showToast('Notes inserted successfully!'); }); }// Backdrop click handlers for modals [pasteModal, recentModal, draftModal].forEach(modal => { if (modal) { modal.addEventListener('click', (e) => { if (e.target === modal) { closeModal(modal); } }); } });// Undo / Redo Bindings if (undoBtn) undoBtn.addEventListener('click', undo); if (redoBtn) redoBtn.addEventListener('click', redo);// Search Bar Toggle & Close if (searchToggleBtn && searchBar && searchInput) { searchToggleBtn.addEventListener('click', () => { searchBar.classList.toggle('active'); if (searchBar.classList.contains('active')) { searchInput.focus(); performSearch(); } }); }if (searchCloseBtn && searchBar) { searchCloseBtn.addEventListener('click', () => { searchBar.classList.remove('active'); }); }if (searchInput) searchInput.addEventListener('input', performSearch); if (caseCheck) caseCheck.addEventListener('change', performSearch);if (searchNextBtn) { searchNextBtn.addEventListener('click', () => { if (state.searchMatches.length === 0) return; state.searchMatchIndex = (state.searchMatchIndex + 1) % state.searchMatches.length; highlightMatch(state.searchMatchIndex); }); }if (searchPrevBtn) { searchPrevBtn.addEventListener('click', () => { if (state.searchMatches.length === 0) return; state.searchMatchIndex = (state.searchMatchIndex - 1 + state.searchMatches.length) % state.searchMatches.length; highlightMatch(state.searchMatchIndex); }); }if (replaceBtn) { replaceBtn.addEventListener('click', () => { if (state.searchMatches.length === 0 || state.searchMatchIndex < 0) { showToast('No matches found.', 'error'); return; } const match = state.searchMatches[state.searchMatchIndex]; const text = state.content; const rep = replaceInput ? replaceInput.value : ''; const newText = text.substring(0, match.start) + rep + text.substring(match.end); setContent(newText); showToast('Replacement made.'); }); }if (replaceAllBtn) { replaceAllBtn.addEventListener('click', () => { if (!searchInput || !searchInput.value) return; const query = searchInput.value; const text = state.content; const rep = replaceInput ? replaceInput.value : ''; const flags = caseCheck && caseCheck.checked ? 'g' : 'gi'; try { const escaped = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); const regex = new RegExp(escaped, flags); const count = (text.match(regex) || []).length; if (count === 0) { showToast('No matches to replace.', 'error'); return; } const newText = text.replace(regex, rep); setContent(newText); showToast(`${count} replacements made.`); } catch (e) { showToast('Replace All failed.', 'error'); } }); }// Keyboard Shortcuts document.addEventListener('keydown', (e) => { if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 's') { e.preventDefault(); saveNote(); } else if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'f') { e.preventDefault(); if (searchBar && searchInput) { searchBar.classList.add('active'); searchInput.focus(); performSearch(); } } else if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'z') { e.preventDefault(); if (e.shiftKey) { redo(); } else { undo(); } } else if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'y') { e.preventDefault(); redo(); } else if (e.key === 'Escape') { if (closeActiveModal()) { e.preventDefault(); } } });if (saveBtn) saveBtn.addEventListener('click', saveNote); if (recentBtn) recentBtn.addEventListener('click', openRecentModal); if (recentCloseBtn && recentModal) recentCloseBtn.addEventListener('click', () => closeModal(recentModal));// Draft Modal Actions if (draftRecoverBtn && draftModal) { draftRecoverBtn.addEventListener('click', () => { try { const raw = localStorage.getItem(DRAFT_KEY); if (raw) { const draft = JSON.parse(raw); state.title = draft.title || 'Untitled Notes'; if (titleInputEl) titleInputEl.value = state.title; state.mode = draft.mode || 'study'; if (formatStyleSelect) formatStyleSelect.value = state.mode; state.exportFormat = draft.exportFormat || 'txt'; if (exportFormatSelect) exportFormatSelect.value = state.exportFormat; state.formattedContent = draft.formattedContent || ''; state.formattedStale = false; state.structure = draft.structure || state.structure; state.currentNoteId = draft.currentNoteId || null;if (draft.content) { state.history = [draft.content]; state.historyIndex = 0; updateUndoRedoButtons(); setContentCore(draft.content); updateStats(draft.content); renderPreview(); } state.dirty = true; updateSaveState('Unsaved changes'); performSearch(); showToast('Draft recovered.'); } } catch (e) { localStorage.removeItem(DRAFT_KEY); } closeModal(draftModal); }); }if (draftDiscardBtn && draftModal) { draftDiscardBtn.addEventListener('click', () => { try { localStorage.removeItem(DRAFT_KEY); } catch (e) {} closeModal(draftModal); showToast('Draft discarded.'); }); }// Initialization & Draft Recovery Check on Startup try { // Restore Theme const savedTheme = localStorage.getItem(THEME_KEY); if (savedTheme === 'dark' || savedTheme === 'light') { setTheme(savedTheme); } else { setTheme('light'); }loadNotesFromStorage();const draftRaw = localStorage.getItem(DRAFT_KEY); if (draftRaw) { const draft = JSON.parse(draftRaw); if (draft && (draft.content || draft.title !== 'Untitled Notes')) { openModal(draftModal, draftRecoverBtn); return true; } }if (editorEl) { const initialText = editorEl.value || ''; state.content = initialText; state.history = [initialText]; state.historyIndex = 0; updateUndoRedoButtons(); updateStats(initialText); renderPreview(); if (initialText.trim()) { updateSaveState('Unsaved changes'); } } if (titleInputEl) { state.title = titleInputEl.value.trim() || 'Untitled Notes'; } performSearch(); } catch (e) { try { localStorage.removeItem(DRAFT_KEY); } catch (err) {} }return true; }if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initApp, { once: true }); } else { initApp(); }// Fallback lightweight MutationObserver for dynamic Elementor widget hydration const observer = new MutationObserver(() => { const root = document.getElementById('ai-notes-smart-copy'); if (root && root.dataset.appInitialized !== 'true') { if (initApp()) { observer.disconnect(); } } }); observer.observe(document.body, { childList: true, subtree: true });})();