(function () { 'use strict'; var serverUrl = ''; var noteId = null; var lastBody = ''; var autosaveTimer = null; var noteEl = document.getElementById('note'); var userEl = document.getElementById('user'); var saveBtn = document.getElementById('save'); var captureBtn = document.getElementById('capture-page'); var statusEl = document.getElementById('status'); var userOptsBtn = document.getElementById('open-options'); function showStatus(msg, ok) { statusEl.textContent = msg; statusEl.className = 'status ' + (ok ? 'ok' : 'err'); if (ok) setTimeout(function () { if (statusEl.textContent === msg) statusEl.textContent = ''; }, 3000); } function currentBody() { return noteEl.value; } async function loadUsers() { try { const r = await browser.runtime.sendMessage({ kind: 'list_users' }); const users = (r && r.users) || []; const saved = await browser.storage.sync.get('username').then(x => x.username); userEl.innerHTML = ''; for (const u of users) { const opt = document.createElement('option'); opt.value = u.name; opt.textContent = u.name; userEl.appendChild(opt); } if (saved && [...userEl.options].some(o => o.value === saved)) { userEl.value = saved; } } catch (e) { showStatus('Cannot load users: ' + e.message, false); } } async function captureContext() { try { const tabs = await browser.tabs.query({ active: true, currentWindow: true }); if (!tabs.length || tabs[0].id == null) return; const ctx = await browser.tabs.sendMessage(tabs[0].id, { kind: 'get_context' }, { frameId: 0 }); if (ctx && ctx.selection && !noteEl.value) { noteEl.value = ctx.selection; } if (ctx) { noteEl.dataset.pageTitle = ctx.title || ''; noteEl.dataset.pageUrl = ctx.url || ''; } } catch (e) { // no selection / content script unavailable on this page — ignore } } async function capturePage() { var title = noteEl.dataset.pageTitle || ''; var url = noteEl.dataset.pageUrl || ''; if (!title && !url) { showStatus('No page to capture', false); return; } var link = '[' + (title || url) + '](' + (url || '') + ')'; var v = noteEl.value; if (v && !/\n$/.test(v)) v += '\n'; noteEl.value = v + link + ' #bookmark\n'; captureBtn.disabled = true; showStatus('Capturing full page…', true); try { const tabs = await browser.tabs.query({ active: true, currentWindow: true }); if (!tabs.length || tabs[0].id == null) { showStatus('No active tab ', false); return; } const shot = await browser.runtime.sendMessage({ kind: 'capture_full_page', tabId: tabs[0].id, windowId: tabs[0].windowId, }); const r = await browser.runtime.sendMessage({ kind: 'upload_attachment', dataUrl: shot.dataUrl, filename: 'page.png', username: userEl.value, }); noteEl.value += '![Screenshot](' + r.url + ')\n'; showStatus('Full-page screenshot attached', true); } catch (e) { showStatus('Screenshot failed: ' + e.message, false); } finally { captureBtn.disabled = false; } noteEl.focus(); scheduleAutosave(); } async function save() { var body = currentBody(); if (!body.trim()) { showStatus('Nothing to save', false); return; } if (body === lastBody && noteId) return; saveBtn.disabled = true; try { const note = await browser.runtime.sendMessage({ kind: 'save_note', id: noteId, body: body, username: userEl.value, }); noteId = note.id; lastBody = body; var tags = (note.tags || []).map(function (t) { return '#' + t; }).join(' '); showStatus('Saved' + (tags ? ' · ' + tags : ''), true); } catch (e) { showStatus('Error: ' + e.message, false); } finally { saveBtn.disabled = false; } } function scheduleAutosave() { if (autosaveTimer) clearTimeout(autosaveTimer); autosaveTimer = setTimeout(function () { autosaveTimer = null; save(); }, 8000); } noteEl.addEventListener('input', scheduleAutosave); userEl.addEventListener('change', function () { browser.storage.sync.set({ username: userEl.value }); }); document.getElementById('logo').addEventListener('click', function () { browser.storage.sync.get('serverUrl').then(function (r) { var url = (r.serverUrl || '').replace(/\/+$/, ''); if (url) browser.tabs.create({ url: url }); }); }); saveBtn.addEventListener('click', function () { if (autosaveTimer) { clearTimeout(autosaveTimer); autosaveTimer = null; } save(); }); captureBtn.addEventListener('click', function () { if (autosaveTimer) { clearTimeout(autosaveTimer); autosaveTimer = null; } capturePage(); }); userOptsBtn.addEventListener('click', function (e) { e.preventDefault(); browser.runtime.openOptionsPage(); }); function updateIndicator() { var el = document.getElementById('server-indicator'); var display = serverUrl ? serverUrl.replace(/^https?:\/\//, '') : 'Set server URL…'; el.textContent = display; el.title = serverUrl || ''; } browser.storage.sync.get('serverUrl').then(function (r) { serverUrl = (r.serverUrl || '').replace(/\/+$/, ''); updateIndicator(); loadUsers(); }); captureContext(); noteEl.focus(); })();