// Bookmark Manipulation Utilities // Handles bookmark operations for synchronization with LinkSyncServer (function() { 'use strict'; const BookmarkUtils = { // Parse Firefox bookmark data parseBookmark(bookmark) { return { id: bookmark.id, url: bookmark.url, title: bookmark.title, description: bookmark.description, notes: bookmark.description || bookmark.notes || '', tags: bookmark.tags || [], favicon_url: bookmark.faviconUrl || bookmark.favicon_url || null, path: bookmark.folder || bookmark.path || '', created_at: bookmark.dateAdded, updated_at: bookmark.lastModified, visit_count: bookmark.count || 0, is_bookmarked: bookmark.isBookmarked || false }; }, // Build bookmark for API buildBookmarkData(data) { return { url: data.url || '', title: data.title || '', description: data.description || '', notes: data.notes || '', tags: Array.isArray(data.tags) ? data.tags : data.tags.split(',').map(t => t.trim()), favicon_url: data.favicon_url || null, path: data.folder || data.path || '', visit_count: data.visit_count || 0, is_bookmarked: data.is_bookmarked || false }; }, // Get page data for auto-fill async getPageData() { try { // Extract URL from active tab const activeTab = await browser.tabs.query({active: true, current: true}); const url = activeTab[0]?.url || ''; // Extract title from active tab const title = activeTab[0]?.title || ''; // Extract description from meta tags const description = await this.getMetaDescription(url); return { url, title, description }; } catch (error) { console.error('Failed to get page data:', error); return {}; } }, // Get meta description from page async getMetaDescription(url) { try { const tabId = await browser.tabs.query({active: true, current: true}); const tabIdValue = tabId[0]?.id; if (!tabIdValue) { return ''; } const content = await browser.tabs.sendMessage(tabIdValue, { action: 'getMetaDescription' }); return content?.description || ''; } catch (error) { // Content script not injected or error return ''; } }, // Format tags as JSON array formatTags(tagString) { if (!tagString) { return []; } return tagString.split(',').map(t => t.trim()).filter(t => t.length > 0); }, // Parse JSON string to bookmark data parseJsonData(jsonString) { try { return JSON.parse(jsonString); } catch (e) { console.error('Failed to parse bookmark JSON:', e); return null; } }, // Get bookmark URL from bookmark object getBookmarkUrl(bookmark) { return bookmark?.url || bookmark?.id || ''; }, // Check if bookmark is a duplicate isDuplicate(existingBookmark, newBookmark) { // Two bookmarks are duplicates if same URL return existingBookmark.url.toLowerCase() === newBookmark.url.toLowerCase(); }, // Merge two bookmarks (for conflict resolution) mergeBookmarks(existing, incoming) { return { id: existing.id || incoming.id, url: incoming.url, title: incoming.title || existing.title, description: incoming.description || existing.description, notes: incoming.notes || existing.notes, tags: Array.from(new Set([...(existing.tags || []), ...(incoming.tags || [])])), favicon_url: incoming.favicon_url || existing.favicon_url, path: incoming.path || existing.path, created_at: existing.created_at, updated_at: new Date().toISOString(), visit_count: incoming.visit_count || existing.visit_count || 0, is_bookmarked: incoming.is_bookmarked || existing.is_bookmarked }; } }; // Export for use in other scripts window.BookmarkUtils = BookmarkUtils; })();