305 lines
7.9 KiB
Markdown
305 lines
7.9 KiB
Markdown
# LinkdingSync Extension - Design Document
|
|
|
|
## Overview
|
|
|
|
`linkdingsync` is a Firefox browser extension that synchronizes bookmarks with a self-hosted Linkding instance. It supports folder hierarchy, bi-directional sync, configurable sync modes, and tag-based bundle management.
|
|
|
|
## Project Location
|
|
|
|
```
|
|
Linkding Browser Extension/LinkdingSync/
|
|
```
|
|
|
|
## Extension Name
|
|
|
|
**`linkdingsync`** - Firefox extension name (manifest.json)
|
|
|
|
---
|
|
|
|
## 1. Data Storage Structure
|
|
|
|
### Configuration (stored in browser.storage.local)
|
|
|
|
```json
|
|
{
|
|
"serverUrl": "https://links.blabber1565.com",
|
|
"apiKey": "your-api-token-here",
|
|
"bundleTag": "bundle_personal_firefox_1",
|
|
"syncMode": "bi-directional",
|
|
"autoGenerateTags": false,
|
|
"lastSyncTimestamp": 1715012345678
|
|
}
|
|
```
|
|
|
|
### Storage Areas
|
|
|
|
- **`browser.storage.local`** - Persistent data per browser profile
|
|
- **`browser.storage.session`** - Temporary session data
|
|
|
|
### Supported Values
|
|
|
|
| Value | Description |
|
|
|-------|------|
|
|
| `bi-directional` | Replicate both directions; keep both versions |
|
|
| `write-only` | Browser is authoritative source; update Linkding only |
|
|
| `read-only` | Linkding is authoritative source; download only |
|
|
|
|
**Default:** `bi-directional`
|
|
|
|
---
|
|
|
|
## 2. Bookmark Notes Structure
|
|
|
|
The `notes` field uses a JSON-compatible structure with versioning for forward compatibility:
|
|
|
|
```json
|
|
{
|
|
"version": 1.0,
|
|
"path": "Work/Resources/Development",
|
|
"userNotes": "Development resources and references",
|
|
"autoTags": [
|
|
{"name": "Work"},
|
|
{"name": "Resources"},
|
|
{"name": "Development"}
|
|
],
|
|
"bundleTag": "bundle_personal_firefox_1"
|
|
}
|
|
```
|
|
|
|
### Display Format
|
|
- Only show `userNotes` in the UI
|
|
- `path` and `autoTags` are hidden from regular users
|
|
|
|
### Version Handling
|
|
|
|
- **version 1.0**: Basic structured format with path, userNotes, autoTags
|
|
- **version 2.0**: Adds bundleTag field for tag-based bundle identification
|
|
- **Extension version tracking**: Uses extension version number for notes version
|
|
- **Backward compatibility**:
|
|
- Old bookmarks without structured notes are detected
|
|
- Non-JSON notes are migrated to structured format
|
|
- Old notes get `version: 1.0` and existing text in `userNotes`
|
|
- Future fields are ignored by older versions
|
|
|
|
### Auto-generate Tags Setting
|
|
- **Default:** `false` (disabled)
|
|
- When `true`, extracts folder names from `path` as tag suggestions
|
|
- User must organize folders intentionally for tag auto-generation to work correctly
|
|
|
|
---
|
|
|
|
## 3. Bundle/Tag Configuration
|
|
|
|
Instead of creating actual Linkding bundles, we use Linkding's "required tags" feature:
|
|
|
|
### Bundle Tag Convention
|
|
|
|
All bookmarks in a bundle must have the bundle tag. The bundle tag name follows this pattern:
|
|
```
|
|
bundle_{BUNDLE_NAME}_{BROWSER}
|
|
```
|
|
|
|
Examples:
|
|
- `bundle_personal_firefox_1`
|
|
- `bundle_work_chrome_1`
|
|
- `bundle_personal_edge_1`
|
|
|
|
### Linkding Query Parameters
|
|
|
|
In Linkding, create a bundle with these parameters:
|
|
- **Search:** (empty)
|
|
- **Required tags:** `{bundleTag}`
|
|
- **Any tags:** (empty)
|
|
- **All tags:** (empty)
|
|
- **Excluded tags:** (empty)
|
|
|
|
This means all bookmarks with the bundle tag appear in this bundle.
|
|
|
|
### Updating Extension Version
|
|
|
|
The extension version is used as the notes version:
|
|
- Extension v1.0.x → notes version 1.0
|
|
- Extension v2.0.x → notes version 2.0
|
|
- Extension v1.0.1 → notes version 1.0 (patch versions don't change notes version)
|
|
|
|
---
|
|
|
|
## 4. Extension File Structure
|
|
|
|
```
|
|
LinkdingSync/
|
|
├── manifest.json # Firefox manifest v2
|
|
├── popup.html # Main extension popup
|
|
├── popup.css # Popup styling
|
|
├── popup.js # Popup UI logic
|
|
├── background.html # Settings/config page
|
|
├── background.js # Service worker
|
|
├── README.md # User documentation
|
|
├── docs/
|
|
│ ├── design.md # Design document
|
|
│ └── TODOs.txt # Version compatibility notes
|
|
└── icons/
|
|
├── icon-48.svg # 48x48 icon
|
|
└── icon-96.svg # 96x96 icon
|
|
```
|
|
|
|
---
|
|
|
|
## 5. Key Features
|
|
|
|
### Popup UI
|
|
- Quick bookmark add with optional notes
|
|
- Sync status indicator
|
|
- Settings button → opens config page
|
|
|
|
### Config Page (`background.html`)
|
|
- Server URL input (with validation)
|
|
- API key input (with "Get from Linkding Settings" guidance)
|
|
- Bundle tag input (e.g., "bundle_personal_firefox_1")
|
|
- Sync mode selector (`bi-directional` | `write-only` | `read-only`)
|
|
- Auto-generate tags toggle
|
|
- Last sync timestamp (human-readable with timezone)
|
|
- Test connection button
|
|
- Save Settings button
|
|
- Reset config button
|
|
|
|
### Background Service
|
|
- Monitor bookmark events (add, remove, modify)
|
|
- Perform sync operations with Linkding API
|
|
- Cache recent API responses
|
|
- Handle errors and show notifications
|
|
- Apply bundle tag to all new bookmarks
|
|
- Migrate old notes to structured format
|
|
|
|
---
|
|
|
|
## 6. Sync Logic Flow
|
|
|
|
```
|
|
1. Browser bookmark change detected
|
|
↓
|
|
2. Check syncMode:
|
|
- read-only: download from Linkding only
|
|
- write-only: sync to Linkding only
|
|
- bi-directional: sync both directions
|
|
↓
|
|
3. For new bookmarks:
|
|
- Add bundleTag to notes
|
|
- Check if URL already in Linkding
|
|
- If no → create new bookmark with bundle tag
|
|
- If yes + different URL → create new bookmark
|
|
- If yes + same URL → update notes (keep title/description)
|
|
↓
|
|
4. For updates (same URL, different folder):
|
|
- Update path in notes
|
|
- Merge with existing notes
|
|
- Apply sync mode rules
|
|
↓
|
|
5. For deletions:
|
|
- write-only → delete from Linkding
|
|
- read-only → ignore (keep Linkding version)
|
|
- bi-directional → delete from Linkding
|
|
↓
|
|
6. Migrate old notes:
|
|
- If notes not JSON or lacks version field → treat as old notes
|
|
- Convert to structured format with version 1.0
|
|
- Preserve existing content in userNotes
|
|
```
|
|
|
|
---
|
|
|
|
## 7. Notes Migration
|
|
|
|
### Old Notes Detection
|
|
|
|
Old notes are detected if:
|
|
- `notes` is not valid JSON, OR
|
|
- `notes` doesn't contain a `version` field
|
|
|
|
### Migration Process
|
|
|
|
1. Parse existing notes
|
|
2. If invalid/non-JSON → create structured notes with:
|
|
```json
|
|
{
|
|
"version": 1.0,
|
|
"path": "",
|
|
"userNotes": "<existing text here>",
|
|
"autoTags": [],
|
|
"bundleTag": "<from config>"
|
|
}
|
|
```
|
|
3. If valid but old version → update version field
|
|
4. If same or newer version → keep as-is
|
|
|
|
### Forward Compatibility
|
|
|
|
When new fields are added to notes structure:
|
|
- Older extension versions ignore unknown fields
|
|
- Newer extension versions add new fields
|
|
- This allows gradual feature rollouts
|
|
|
|
---
|
|
|
|
## 8. API Endpoints Used
|
|
|
|
### Authentication
|
|
```
|
|
Authorization: Token <Token>
|
|
```
|
|
|
|
### Bookmarks
|
|
- `GET /api/bookmarks/` - List bookmarks
|
|
- `GET /api/bookmarks/check/?url=...` - Check if URL is already bookmarked
|
|
- `POST /api/bookmarks/` - Create bookmark
|
|
- `PUT/PATCH /api/bookmarks/<id>/` - Update bookmark
|
|
- `DELETE /api/bookmarks/<id>/` - Delete bookmark
|
|
|
|
---
|
|
|
|
## 9. Implementation Status
|
|
|
|
### Phase 1: Core Setup
|
|
- [x] Create manifest.json with options_ui
|
|
- [x] Create popup HTML/CSS/JS
|
|
- [x] Create background service worker
|
|
- [x] Implement storage helpers
|
|
|
|
### Phase 2: Sync Logic
|
|
- [x] Implement bookmark manipulation
|
|
- [x] Implement notes parser with versioning
|
|
- [x] Implement sync logic
|
|
- [x] Implement conflict resolution
|
|
|
|
### Phase 3: Configuration UI
|
|
- [x] Create config page
|
|
- [x] Implement config form logic
|
|
- [x] Add API key guidance
|
|
|
|
### Phase 4: Polish
|
|
- [x] Add icons
|
|
- [x] Add error handling
|
|
- [x] Add notifications
|
|
- [x] Implement notes migration
|
|
- [x] Implement tag-based bundle approach
|
|
|
|
---
|
|
|
|
## 10. Version History
|
|
|
|
| Version | Date | Changes |
|
|
|---------|------|---------|
|
|
| 0.1.0 | 2026-05-06 | Initial design document |
|
|
| 1.0.0 | 2026-05-06 | Initial implementation |
|
|
| 1.0.1 | TBD | Tag-based bundle support |
|
|
| 1.0.2 | TBD | Notes version migration |
|
|
|
|
---
|
|
|
|
## 11. Notes
|
|
|
|
This document should be referenced during implementation to ensure all requirements are met. Any deviations from this design should be documented here.
|
|
|
|
---
|
|
|
|
**Last Updated:** 2026-05-06 |