- // ==UserScript==
- // @name Professional Website Notes Manager
- // @namespace http://tampermonkey.net/
- // @version 0.5
- // @description Professional notes manager with editable URLs, modern interface, and quick delete functionality
- // @author Byakuran
- // @match https://*/*
- // @grant GM_setValue
- // @grant GM_getValue
- // @grant GM_registerMenuCommand
- // ==/UserScript==
-
- (function() {
- 'use strict';
-
- const defaultOptions = {
- darkMode: window.matchMedia('(prefers-color-scheme: dark)').matches,
- addTimestampToTitle: false,
- shortcuts: {
- newNote: { ctrlKey: true, shiftKey: true, key: 'S' },
- currentPageNotes: { ctrlKey: true, shiftKey: true, key: 'C' },
- allNotes: { ctrlKey: true, shiftKey: true, key: 'L' }
- }
- };
-
- let options = GM_getValue('options', defaultOptions);
- GM_setValue('options', options);
-
- const isDarkMode = options.darkMode;
-
- const darkModeStyles = {
- modal: {
- bg: '#1f2937',
- text: '#f3f4f6'
- },
- input: {
- bg: '#374151',
- border: '#4b5563',
- text: '#f3f4f6'
- },
- button: {
- primary: '#3b82f6',
- primaryHover: '#2563eb',
- secondary: '#4b5563',
- secondaryHover: '#374151',
- text: '#ffffff'
- },
- listItem: {
- bg: '#374151',
- bgHover: '#4b5563',
- text: '#f3f4f6'
- }
- };
-
- const lightModeStyles = {
- modal: {
- bg: '#ffffff',
- text: '#111827'
- },
- input: {
- bg: '#f9fafb',
- border: '#e5e7eb',
- text: '#111827'
- },
- button: {
- primary: '#3b82f6',
- primaryHover: '#2563eb',
- secondary: '#f3f4f6',
- secondaryHover: '#e5e7eb',
- text: '#ffffff'
- },
- listItem: {
- bg: '#ffffff',
- bgHover: '#f9fafb',
- text: '#1f2937'
- }
- };
-
- const currentTheme = isDarkMode ? darkModeStyles : lightModeStyles;
-
- const styles = `
- .notes-modal {
- position: fixed;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- background: ${currentTheme.modal.bg};
- color: ${currentTheme.modal.text};
- padding: 32px;
- border-radius: 16px;
- box-shadow: 0 8px 32px rgba(0,0,0,0.25);
- z-index: 10000;
- max-width: 700px;
- width: 90%;
- font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
- }
- .notes-overlay {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(0,0,0,${isDarkMode ? '0.8' : '0.7'});
- z-index: 9999;
- backdrop-filter: blur(4px);
- }
- .notes-input {
- width: 100%;
- margin: 12px 0;
- padding: 12px 16px;
- border: 2px solid ${currentTheme.input.border};
- border-radius: 8px;
- font-size: 15px;
- transition: all 0.2s ease;
- background: ${currentTheme.input.bg};
- color: ${currentTheme.input.text};
- box-sizing: border-box;
- }
- .notes-input:focus {
- outline: none;
- border-color: #3b82f6;
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
- }
- .notes-textarea {
- width: 100%;
- height: 200px;
- margin: 12px 0;
- padding: 16px;
- border: 2px solid ${currentTheme.input.border};
- border-radius: 8px;
- font-size: 15px;
- resize: vertical;
- transition: all 0.2s ease;
- background: ${currentTheme.input.bg};
- color: ${currentTheme.input.text};
- line-height: 1.5;
- box-sizing: border-box;
- }
- .notes-textarea:focus {
- outline: none;
- border-color: #3b82f6;
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
- }
- .notes-button {
- background: ${currentTheme.button.primary};
- color: ${currentTheme.button.text};
- border: none;
- padding: 12px 24px;
- border-radius: 8px;
- cursor: pointer;
- margin: 5px;
- font-size: 15px;
- font-weight: 500;
- transition: all 0.2s ease;
- }
- .notes-button:hover {
- background: ${currentTheme.button.primaryHover};
- transform: translateY(-1px);
- }
- .notes-button.secondary {
- background: ${currentTheme.button.secondary};
- color: ${isDarkMode ? '#f3f4f6' : '#4b5563'};
- }
- .notes-button.secondary:hover {
- background: ${currentTheme.button.secondaryHover};
- }
- .notes-button.delete {
- background: #ef4444;
- }
- .notes-button.delete:hover {
- background: #dc2626;
- }
- .notes-button.edit {
- background: #10b981;
- }
- .notes-button.edit:hover {
- background: #059669;
- }
- .notes-list-item {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 16px;
- border: 1px solid ${currentTheme.input.border};
- border-radius: 8px;
- margin: 8px 0;
- cursor: pointer;
- transition: all 0.2s ease;
- background: ${currentTheme.listItem.bg};
- color: ${currentTheme.listItem.text};
- }
- .notes-list-item:hover {
- background: ${currentTheme.listItem.bgHover};
- transform: translateY(-1px);
- box-shadow: 0 4px 12px rgba(0,0,0,${isDarkMode ? '0.3' : '0.05'});
- }
- .close-button {
- position: absolute;
- top: 16px;
- right: 16px;
- cursor: pointer;
- font-size: 24px;
- color: ${isDarkMode ? '#9ca3af' : '#6b7280'};
- transition: all 0.2s;
- width: 32px;
- height: 32px;
- display: flex;
- align-items: center;
- justify-content: center;
- border-radius: 6px;
- }
- .close-button:hover {
- color: ${isDarkMode ? '#f3f4f6' : '#111827'};
- background: ${isDarkMode ? '#374151' : '#f3f4f6'};
- }
- .modal-title {
- font-size: 20px;
- font-weight: 600;
- margin-bottom: 24px;
- color: ${currentTheme.modal.text};
- }
- .url-text {
- font-size: 14px;
- color: ${isDarkMode ? '#9ca3af' : '#6b7280'};
- word-break: break-all;
- margin-bottom: 16px;
- padding: 8px 12px;
- background: ${isDarkMode ? '#374151' : '#f3f4f6'};
- border-radius: 6px;
- }
- .timestamp {
- font-size: 12px;
- color: ${isDarkMode ? '#9ca3af' : '#6b7280'};
- margin-top: 4px;
- }
- .delete-note-button {
- background: none;
- border: none;
- color: #ef4444;
- font-size: 18px;
- cursor: pointer;
- padding: 4px 8px;
- border-radius: 4px;
- transition: all 0.2s ease;
- }
- .delete-note-button:hover {
- background: #ef4444;
- color: #ffffff;
- }
- `;
-
- const styleSheet = document.createElement("style");
- styleSheet.innerText = styles;
- document.head.appendChild(styleSheet);
-
- function showOptionsMenu() {
- const container = document.createElement('div');
- container.innerHTML = `
- <h3 class="modal-title">Options</h3>
- <div>
- <label>
- <input type="checkbox" id="darkModeToggle" ${options.darkMode ? 'checked' : ''}>
- Dark Mode
- </label>
- </div>
- <div style="margin-top: 10px;">
- <label>
- <input type="checkbox" id="timestampToggle" ${options.addTimestampToTitle ? 'checked' : ''}>
- Add timestamp to note titles
- </label>
- </div>
- <h4 style="margin-top: 20px;">Keyboard Shortcuts</h4>
- <div>
- <label>New Note:
- <input type="text" id="newNoteShortcut" value="${getShortcutString(options.shortcuts.newNote)}">
- </label>
- </div>
- <div>
- <label>Current Page Notes:
- <input type="text" id="currentPageNotesShortcut" value="${getShortcutString(options.shortcuts.currentPageNotes)}">
- </label>
- </div>
- <div>
- <label>All Notes:
- <input type="text" id="allNotesShortcut" value="${getShortcutString(options.shortcuts.allNotes)}">
- </label>
- </div>
- <button id="saveOptions" class="notes-button" style="margin-top: 20px;">Save Options</button>
- `;
-
- createModal(container);
- document.getElementById('saveOptions').onclick = saveOptions;
- }
-
- function getShortcutString(shortcut) {
- let str = '';
- if (shortcut.ctrlKey) str += 'Ctrl+';
- if (shortcut.shiftKey) str += 'Shift+';
- if (shortcut.altKey) str += 'Alt+';
- str += shortcut.key.toUpperCase();
- return str;
- }
-
- function parseShortcutString(str) {
- const parts = str.toLowerCase().split('+');
- return {
- ctrlKey: parts.includes('ctrl'),
- shiftKey: parts.includes('shift'),
- altKey: parts.includes('alt'),
- key: parts[parts.length - 1]
- };
- }
-
- function saveOptions() {
- options.darkMode = document.getElementById('darkModeToggle').checked;
- options.addTimestampToTitle = document.getElementById('timestampToggle').checked;
- options.shortcuts.newNote = parseShortcutString(document.getElementById('newNoteShortcut').value);
- options.shortcuts.currentPageNotes = parseShortcutString(document.getElementById('currentPageNotesShortcut').value);
- options.shortcuts.allNotes = parseShortcutString(document.getElementById('allNotesShortcut').value);
-
- GM_setValue('options', options);
- alert('Options saved. Please refresh the page for changes to take effect.');
- }
-
-
- GM_registerMenuCommand('Toggle Dark Mode', () => {
- const newMode = !isDarkMode;
- GM_setValue('darkMode', newMode);
- location.reload();
- });
-
- function createModal(content) {
- const overlay = document.createElement('div');
- overlay.className = 'notes-overlay';
-
- const modal = document.createElement('div');
- modal.className = 'notes-modal';
-
- const closeButton = document.createElement('span');
- closeButton.className = 'close-button';
- closeButton.textContent = '×';
- closeButton.onclick = () => overlay.remove();
-
- modal.appendChild(closeButton);
- modal.appendChild(content);
- overlay.appendChild(modal);
- document.body.appendChild(overlay);
-
- const escapeListener = (e) => {
- if (e.key === 'Escape') {
- overlay.remove();
- document.removeEventListener('keydown', escapeListener);
- }
- };
- document.addEventListener('keydown', escapeListener);
- }
-
- function getAllNotes() {
- return GM_getValue('website-notes', {});
- }
-
- function saveNote(title, url, content, timestamp = Date.now(), pinned = false) {
- const notes = getAllNotes();
- if (!notes[url]) notes[url] = [];
-
- // Add timestamp to title if the option is enabled
- let finalTitle = title;
- if (options.addTimestampToTitle) {
- const date = new Date(timestamp);
- const formattedDate = date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
- finalTitle = `${title} [${formattedDate}]`;
- }
-
- notes[url].push({ title: finalTitle, content, timestamp, pinned });
- GM_setValue('website-notes', notes);
- }
-
- function updateNote(oldUrl, index, title, newUrl, content, pinned) {
- const notes = getAllNotes();
- deleteNote(oldUrl, index);
- saveNote(title, newUrl, content, notes[oldUrl][index].timestamp, pinned);
- }
-
- function togglePinNote(url, index) {
- const notes = getAllNotes();
- if (notes[url] && notes[url][index]) {
- notes[url][index].pinned = !notes[url][index].pinned;
- GM_setValue('website-notes', notes);
- }
- }
-
- function deleteNote(url, index) {
- const notes = getAllNotes();
- if (notes[url]) {
- notes[url].splice(index, 1);
- if (notes[url].length === 0) delete notes[url];
- GM_setValue('website-notes', notes);
- }
- }
-
- function showNoteForm(editMode = false, existingNote = null, url = null, index = null) {
- const container = document.createElement('div');
- container.innerHTML = `<h3 class="modal-title">${editMode ? 'Edit Note' : 'Create New Note'}</h3>`;
-
- const titleInput = document.createElement('input');
- titleInput.className = 'notes-input';
- titleInput.placeholder = 'Enter title';
- titleInput.value = editMode ? existingNote.title : '';
-
- const urlInput = document.createElement('input');
- urlInput.className = 'notes-input';
- urlInput.placeholder = 'Enter URL or URL pattern (e.g., https://domain.com/*)';
- urlInput.value = editMode ? url : window.location.href;
-
- const patternHelp = document.createElement('div');
- patternHelp.style.fontSize = '12px';
- patternHelp.style.color = isDarkMode ? '#9ca3af' : '#6b7280';
- patternHelp.style.marginTop = '-8px';
- patternHelp.style.marginBottom = '8px';
- patternHelp.innerHTML = 'Use * for wildcard matching (e.g., https://domain.com/*)';
-
- const contentArea = document.createElement('textarea');
- contentArea.className = 'notes-textarea';
- contentArea.placeholder = 'Enter your notes here';
- contentArea.value = editMode ? existingNote.content : '';
-
- const buttonGroup = document.createElement('div');
- buttonGroup.className = 'button-group';
-
- const saveButton = document.createElement('button');
- saveButton.className = 'notes-button';
- saveButton.textContent = editMode ? 'Update Note' : 'Save Note';
- saveButton.onclick = () => {
- if (titleInput.value && contentArea.value) {
- if (editMode) {
- updateNote(url, index, titleInput.value, urlInput.value, contentArea.value);
- } else {
- saveNote(titleInput.value, urlInput.value, contentArea.value);
- }
- container.parentElement.parentElement.remove();
- showCurrentPageNotes();
- }
- };
-
- const cancelButton = document.createElement('button');
- cancelButton.className = 'notes-button secondary';
- cancelButton.textContent = 'Cancel';
- cancelButton.onclick = () => container.parentElement.parentElement.remove();
-
- buttonGroup.appendChild(saveButton);
- buttonGroup.appendChild(cancelButton);
-
- container.appendChild(titleInput);
- container.appendChild(urlInput);
- container.appendChild(patternHelp);
- container.appendChild(contentArea);
- container.appendChild(buttonGroup);
-
- createModal(container);
- }
-
- function formatDate(timestamp) {
- return new Date(timestamp).toLocaleString();
- }
-
- function showNoteContent(note, url, index) {
- const container = document.createElement('div');
-
- // Function to convert URLs to clickable links
- function linkify(text) {
- // URL pattern for matching
- const urlPattern = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
-
- // Replace URLs with anchor tags
- const linkedText = text.replace(urlPattern, function(url) {
- return `<a href="${url}" target="_blank" style="color: #3b82f6; text-decoration: underline; word-break: break-all;" onclick="event.stopPropagation();">${url}</a>`;
- });
-
- // Convert line breaks to <br> tags and maintain whitespace
- return linkedText.replace(/\n/g, '<br>').replace(/\s{2,}/g, function(space) {
- return ' ' + ' '.repeat(space.length - 1);
- });
- }
-
- container.innerHTML = `
- <h3 class="modal-title">${note.title}</h3>
- <div class="url-text">${url}</div>
- <div class="timestamp">Created: ${formatDate(note.timestamp)}</div>
- <div style="margin: 16px 0; line-height: 1.6;">${linkify(note.content)}</div>
- `;
-
- const buttonGroup = document.createElement('div');
- buttonGroup.className = 'button-group';
-
- const editButton = document.createElement('button');
- editButton.className = 'notes-button edit';
- editButton.textContent = 'Edit';
- editButton.onclick = () => {
- container.parentElement.parentElement.remove();
- showNoteForm(true, note, url, index);
- };
-
- const deleteButton = document.createElement('button');
- deleteButton.className = 'notes-button delete';
- deleteButton.textContent = 'Delete';
- deleteButton.onclick = () => {
- if (confirm('Are you sure you want to delete this note?')) {
- deleteNote(url, index);
- container.parentElement.parentElement.remove();
- showCurrentPageNotes();
- }
- };
-
- const pinButton = document.createElement('button');
- pinButton.className = `notes-button ${note.pinned ? 'secondary' : ''}`;
- pinButton.textContent = note.pinned ? 'Unpin' : 'Pin';
- pinButton.onclick = () => {
- togglePinNote(url, index);
- pinButton.textContent = note.pinned ? 'Pin' : 'Unpin';
- pinButton.className = `notes-button ${!note.pinned ? 'secondary' : ''}`;
- displayPinnedNotes();
- };
-
- buttonGroup.appendChild(editButton);
- buttonGroup.appendChild(deleteButton);
- buttonGroup.appendChild(pinButton);
- container.appendChild(buttonGroup);
-
- createModal(container);
- }
-
- function displayPinnedNotes() {
- const notes = getAllNotes();
- const currentUrl = window.location.href;
- let pinnedNotesContainer = document.getElementById('pinned-notes-container');
-
- if (!pinnedNotesContainer) {
- pinnedNotesContainer = document.createElement('div');
- pinnedNotesContainer.id = 'pinned-notes-container';
- pinnedNotesContainer.style.position = 'fixed';
- pinnedNotesContainer.style.top = '10px';
- pinnedNotesContainer.style.right = '10px';
- pinnedNotesContainer.style.zIndex = '9999';
- pinnedNotesContainer.style.maxWidth = '300px';
- document.body.appendChild(pinnedNotesContainer);
- }
-
- pinnedNotesContainer.innerHTML = '';
-
- for (const url in notes) {
- if (doesUrlMatchPattern(url, currentUrl)) {
- notes[url].forEach((note, index) => {
- if (note.pinned) {
- const noteDiv = document.createElement('div');
- noteDiv.className = 'pinned-note';
- noteDiv.style.background = currentTheme.listItem.bg;
- noteDiv.style.color = currentTheme.listItem.text;
- noteDiv.style.padding = '10px';
- noteDiv.style.margin = '5px 0';
- noteDiv.style.borderRadius = '8px';
- noteDiv.style.boxShadow = '0 2px 4px rgba(0,0,0,0.1)';
- noteDiv.style.cursor = 'pointer';
- noteDiv.innerHTML = `<strong>${note.title}</strong>`;
- noteDiv.onclick = () => showNoteContent(note, url, index);
- pinnedNotesContainer.appendChild(noteDiv);
- }
- });
- }
- }
- }
-
-
- function doesUrlMatchPattern(urlPattern, currentUrl) {
- // Escape special characters for regex
- const escapeRegex = (string) => string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
-
- // Convert Tampermonkey-style pattern to regex
- const patternToRegex = (pattern) => {
- const parts = pattern.split('*');
- let regexString = '^';
- for (let i = 0; i < parts.length; i++) {
- regexString += escapeRegex(parts[i]);
- if (i < parts.length - 1) {
- if (parts[i + 1] === '') {
- // '**' matches any number of path segments
- regexString += '.*';
- i++; // Skip the next '*'
- } else {
- // Single '*' matches anything except '/'
- regexString += '[^/]*';
- }
- }
- //Hope everything works.
- }
- // If the pattern ends with '**', allow anything at the end
- if (pattern.endsWith('**')) {
- regexString += '.*';
- } else if (!pattern.endsWith('*')) {
- regexString += '$';
- }
- return new RegExp(regexString);
- };
-
- try {
- const regex = patternToRegex(urlPattern);
- return regex.test(currentUrl);
- } catch (e) {
- console.error('Invalid URL pattern:', e);
- return false;
- }
- }
-
- function showCurrentPageNotes() {
- const notes = getAllNotes();
- const currentUrl = window.location.href;
- let matchingNotes = [];
-
- // Collect all matching notes
- for (const urlPattern in notes) {
- if (doesUrlMatchPattern(urlPattern, currentUrl)) {
- matchingNotes.push({
- pattern: urlPattern,
- notes: notes[urlPattern]
- });
- }
- }
-
- const container = document.createElement('div');
- container.innerHTML = `
- <h3 class="modal-title">Notes for Current Page</h3>
- <div class="url-text">${currentUrl}</div>
- `;
-
- if (matchingNotes.length === 0) {
- container.innerHTML += '<p style="color: #6b7280;">No matching notes found for this page</p>';
- } else {
- matchingNotes.forEach(({pattern, notes: patternNotes}) => {
- const patternDiv = document.createElement('div');
- patternDiv.innerHTML = `<div class="url-text">Pattern: ${pattern}</div>`;
-
- patternNotes.forEach((note, index) => {
- const noteDiv = document.createElement('div');
- noteDiv.className = 'notes-list-item';
- noteDiv.innerHTML = `
- <span style="flex-grow: 1; display: flex; align-items: center;">${note.title}</span>
- <button class="delete-note-button" title="Delete note">×</button>
- `;
-
- noteDiv.onclick = (e) => {
- if (!e.target.classList.contains('delete-note-button')) {
- container.parentElement.parentElement.remove();
- showNoteContent(note, pattern, index);
- }
- };
-
- noteDiv.querySelector('.delete-note-button').onclick = (e) => {
- e.stopPropagation();
- if (confirm('Are you sure you want to delete this note?')) {
- deleteNote(pattern, index);
- noteDiv.remove();
- if (patternNotes.length === 1) {
- patternDiv.remove();
- }
- }
- };
-
- patternDiv.appendChild(noteDiv);
- });
-
- container.appendChild(patternDiv);
- });
- }
-
- // Add help button and dropdown
- const helpButton = document.createElement('button');
- helpButton.textContent = '?';
- helpButton.style.position = 'absolute';
- helpButton.style.top = '16px';
- helpButton.style.right = '56px';
- helpButton.style.width = '32px';
- helpButton.style.height = '32px';
- helpButton.style.borderRadius = '50%';
- helpButton.style.border = 'none';
- helpButton.style.background = isDarkMode ? '#374151' : '#e5e7eb';
- helpButton.style.color = isDarkMode ? '#f3f4f6' : '#4b5563';
- helpButton.style.fontSize = '18px';
- helpButton.style.cursor = 'pointer';
- helpButton.style.display = 'flex';
- helpButton.style.alignItems = 'center';
- helpButton.style.justifyContent = 'center';
- helpButton.title = 'URL Pattern Help';
-
- const helpDropdown = document.createElement('div');
- helpDropdown.style.position = 'absolute';
- helpDropdown.style.top = '52px';
- helpDropdown.style.right = '56px';
- helpDropdown.style.background = isDarkMode ? '#1f2937' : '#ffffff';
- helpDropdown.style.border = `1px solid ${isDarkMode ? '#4b5563' : '#e5e7eb'}`;
- helpDropdown.style.borderRadius = '8px';
- helpDropdown.style.padding = '16px';
- helpDropdown.style.boxShadow = '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)';
- helpDropdown.style.zIndex = '10001';
- helpDropdown.style.display = 'none';
- helpDropdown.style.maxWidth = '300px';
- helpDropdown.style.color = isDarkMode ? '#f3f4f6' : '#4b5563';
- helpDropdown.innerHTML = `
- <strong>URL Pattern Examples:</strong><br>
- - https://domain.com/* (matches entire domain, one level deep)<br>
- - https://domain.com/** (matches entire domain, any number of levels)<br>
- - https://domain.com/specific/* (matches specific path and one level below)<br>
- - https://domain.com/specific/** (matches specific path and any levels below)<br>
- - https://domain.com/*/specific (matches specific ending, one level in between)<br>
- - https://domain.com/**/specific (matches specific ending, any number of levels in between)
- `;
-
- let isDropdownOpen = false;
-
- helpButton.onmouseenter = () => {
- if (!isDropdownOpen) {
- helpDropdown.style.display = 'block';
- }
- };
-
- helpButton.onmouseleave = () => {
- if (!isDropdownOpen) {
- helpDropdown.style.display = 'none';
- }
- };
-
- helpButton.onclick = () => {
- isDropdownOpen = !isDropdownOpen;
- helpDropdown.style.display = isDropdownOpen ? 'block' : 'none';
- };
-
- document.addEventListener('click', (e) => {
- if (isDropdownOpen && e.target !== helpButton && !helpDropdown.contains(e.target)) {
- isDropdownOpen = false;
- helpDropdown.style.display = 'none';
- }
- });
-
- container.appendChild(helpButton);
- container.appendChild(helpDropdown);
-
- createModal(container);
- }
-
- function showAllNotes() {
- const notes = getAllNotes();
- const container = document.createElement('div');
- container.innerHTML = '<h3 class="modal-title">All Notes</h3>';
-
- if (Object.keys(notes).length === 0) {
- container.innerHTML += '<p style="color: #6b7280;">No notes found</p>';
- } else {
- for (const url in notes) {
- const urlDiv = document.createElement('div');
- urlDiv.innerHTML = `<div class="url-text">${url}</div>`;
-
- notes[url].forEach((note, index) => {
- const noteDiv = document.createElement('div');
- noteDiv.className = 'notes-list-item';
- noteDiv.innerHTML = `
- <span style="flex-grow: 1; display: flex; align-items: center;">${note.title}</span>
- <button class="delete-note-button" title="Delete note">×</button>
- `;
-
- noteDiv.onclick = (e) => {
- if (!e.target.classList.contains('delete-note-button')) {
- container.parentElement.parentElement.remove();
- showNoteContent(note, url, index);
- }
- };
-
- noteDiv.querySelector('.delete-note-button').onclick = (e) => {
- e.stopPropagation();
- if (confirm('Are you sure you want to delete this note?')) {
- deleteNote(url, index);
- noteDiv.remove();
- if (notes[url].length === 1) {
- urlDiv.remove();
- }
- }
- };
-
- urlDiv.appendChild(noteDiv);
- });
-
- container.appendChild(urlDiv);
- }
- }
-
- createModal(container);
- }
-
- document.addEventListener('keydown', function(e) {
- if (matchShortcut(e, options.shortcuts.newNote)) {
- e.preventDefault();
- showNoteForm();
- }
- if (matchShortcut(e, options.shortcuts.currentPageNotes)) {
- e.preventDefault();
- showCurrentPageNotes();
- }
- if (matchShortcut(e, options.shortcuts.allNotes)) {
- e.preventDefault();
- showAllNotes();
- }
- });
-
- function matchShortcut(e, shortcut) {
- return e.ctrlKey === shortcut.ctrlKey &&
- e.shiftKey === shortcut.shiftKey &&
- e.altKey === shortcut.altKey &&
- e.key.toLowerCase() === shortcut.key.toLowerCase();
- }
-
- displayPinnedNotes();
-
- // Register menu commands
- GM_registerMenuCommand('New Note', () => showNoteForm());
- GM_registerMenuCommand('View Notes (Current Page)', showCurrentPageNotes);
- GM_registerMenuCommand('View All Notes', showAllNotes);
- GM_registerMenuCommand('Options', showOptionsMenu);
-
- })();