Initial commit: LinkSyncServer and LinkSyncExtension projects with complete documentation, models, API endpoints, tests, and extension implementation
This commit is contained in:
138
LinkSyncExtension/utils/bookmark.js
Normal file
138
LinkSyncExtension/utils/bookmark.js
Normal file
@@ -0,0 +1,138 @@
|
||||
// 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;
|
||||
|
||||
})();
|
||||
Reference in New Issue
Block a user