Skip to content

Commit 0a74aff

Browse files
authored
Merge pull request #3 from ashishjha-96/bug-fixes
fix: High-priority bug fixes for reliability and code quality
2 parents 7e9519a + b284951 commit 0a74aff

26 files changed

+2640
-16
lines changed

chrome-extension/.gitignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Chrome extension gitignore
2+
3+
# Downloaded icons (generated via generate-icons.html)
4+
icons/*.png
5+
6+
# Packaged extension
7+
*.zip
8+
*.crx
9+
10+
# macOS
11+
.DS_Store
12+

chrome-extension/ARCHITECTURE.md

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
# Chrome Extension Architecture
2+
3+
## Overview
4+
5+
The "Import to Markdown" extension extracts webpage content and imports it into your Markdoc collaborative editor.
6+
7+
## Components
8+
9+
```
10+
┌─────────────────────────────────────────────────────────────┐
11+
│ Chrome Extension │
12+
├─────────────────────────────────────────────────────────────┤
13+
│ │
14+
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
15+
│ │ manifest. │ │ popup. │ │ background. │ │
16+
│ │ json │ │ html/js │ │ js │ │
17+
│ └──────────────┘ └──────────────┘ └──────────────┘ │
18+
│ │ │ │ │
19+
│ │ │ │ │
20+
│ ┌──────────────┐ ┌──────────────────────────────┐ │
21+
│ │ content.js │ │ Chrome Storage API │ │
22+
│ └──────────────┘ └──────────────────────────────┘ │
23+
│ │
24+
└─────────────────────────────────────────────────────────────┘
25+
26+
│ Store markdown + open tab
27+
28+
┌─────────────────────────────────────────────────────────────┐
29+
│ Markdoc App │
30+
├─────────────────────────────────────────────────────────────┤
31+
│ │
32+
│ ┌──────────────────────────────────────────────────────┐ │
33+
│ │ App.tsx (initImportBridge) │ │
34+
│ └──────────────────────────────────────────────────────┘ │
35+
│ │ │
36+
│ ▼ │
37+
│ ┌──────────────────────────────────────────────────────┐ │
38+
│ │ importBridge.ts │ │
39+
│ │ - Listen for messages │ │
40+
│ │ - Fetch from Chrome storage │ │
41+
│ │ - Post markdown back to window │ │
42+
│ └──────────────────────────────────────────────────────┘ │
43+
│ │ │
44+
│ ▼ │
45+
│ ┌──────────────────────────────────────────────────────┐ │
46+
│ │ Editor.tsx │ │
47+
│ │ - Check URL param (?import=true) │ │
48+
│ │ - Request import via requestImport() │ │
49+
│ │ - Receive markdown via onImportMarkdown() │ │
50+
│ │ - Convert markdown → BlockNote blocks │ │
51+
│ │ - Insert into editor │ │
52+
│ └──────────────────────────────────────────────────────┘ │
53+
│ │
54+
└─────────────────────────────────────────────────────────────┘
55+
```
56+
57+
## Flow Diagram
58+
59+
### Import Flow
60+
61+
```
62+
User clicks extension → Extract content → Convert to markdown
63+
64+
65+
Store in Chrome storage (key: import_${docId})
66+
67+
68+
Open new tab: markdoc.com/${docId}?import=true
69+
70+
71+
┌────────────────────────────────────────────────────────────────────┐
72+
│ Markdoc App Loads │
73+
├────────────────────────────────────────────────────────────────────┤
74+
│ │
75+
│ 1. App.tsx initializes import bridge │
76+
│ 2. Editor.tsx detects ?import=true parameter │
77+
│ 3. Editor calls requestImport(docId) │
78+
│ 4. importBridge posts message to window │
79+
│ 5. importBridge checks Chrome storage for import_${docId} │
80+
│ 6. importBridge posts markdown back via message │
81+
│ 7. Editor receives markdown via onImportMarkdown() │
82+
│ 8. Editor converts markdown → BlockNote blocks │
83+
│ 9. Editor inserts blocks into document │
84+
│ 10. Clean up storage & URL parameter │
85+
│ │
86+
└────────────────────────────────────────────────────────────────────┘
87+
```
88+
89+
### Copy Flow
90+
91+
```
92+
User clicks "Copy" → Extract content → Convert to markdown → Copy to clipboard
93+
```
94+
95+
## File Responsibilities
96+
97+
### Extension Files
98+
99+
| File | Purpose |
100+
|------|---------|
101+
| `manifest.json` | Extension metadata, permissions, and configuration |
102+
| `popup.html` | User interface for the extension popup |
103+
| `popup.js` | Handles user interactions, content extraction, and Chrome API calls |
104+
| `background.js` | Service worker for cleanup tasks |
105+
| `content.js` | Runs on web pages (currently minimal, extraction done via executeScript) |
106+
107+
### Markdoc Files
108+
109+
| File | Purpose |
110+
|------|---------|
111+
| `frontend/src/lib/importBridge.ts` | Communication bridge between extension and app |
112+
| `frontend/src/App.tsx` | Initializes import bridge on mount |
113+
| `frontend/src/components/Editor.tsx` | Handles import flow and markdown insertion |
114+
115+
## Key Functions
116+
117+
### Extension (popup.js)
118+
119+
```javascript
120+
extractContent(options)
121+
├─ Find main content (article, main, etc.)
122+
├─ Remove unwanted elements (nav, ads, etc.)
123+
├─ Convert HTML → Markdown
124+
│ ├─ Headings: # ## ###
125+
│ ├─ Lists: - or 1.
126+
│ ├─ Links: [text](url)
127+
│ ├─ Images: ![alt](src)
128+
│ ├─ Code: ``` or `
129+
│ └─ Formatting: **bold** *italic*
130+
└─ Add metadata if requested
131+
132+
generateDocId()
133+
└─ Generate random 21-character ID
134+
135+
Import Button Click:
136+
├─ Extract content
137+
├─ Generate doc ID
138+
├─ Store in chrome.storage.local
139+
└─ Open new tab with ?import=true
140+
```
141+
142+
### Markdoc App (importBridge.ts)
143+
144+
```typescript
145+
initImportBridge()
146+
└─ Listen for 'REQUEST_IMPORT' messages
147+
├─ Check Chrome storage for import data
148+
└─ Post 'IMPORT_MARKDOWN' message back
149+
150+
requestImport(docId)
151+
└─ Post 'REQUEST_IMPORT' message to window
152+
153+
onImportMarkdown(docId, callback)
154+
├─ Listen for 'IMPORT_MARKDOWN' messages
155+
└─ Call callback with markdown
156+
```
157+
158+
### Editor (Editor.tsx)
159+
160+
```typescript
161+
useEffect for import:
162+
├─ Check if ?import=true in URL
163+
├─ Call requestImport(docId)
164+
├─ Listen via onImportMarkdown()
165+
├─ Convert markdown → BlockNote blocks
166+
├─ Insert blocks into editor
167+
└─ Clean up URL parameter
168+
```
169+
170+
## Security Considerations
171+
172+
1. **Content Script Permissions**: Minimal - only runs extraction in executeScript
173+
2. **Storage**: Data stored temporarily (max 1 hour, cleaned up)
174+
3. **Cross-Origin**: Uses Chrome storage API which is cross-origin safe
175+
4. **Message Validation**: Checks message types and source
176+
177+
## Data Storage
178+
179+
### Chrome Storage Schema
180+
181+
```typescript
182+
{
183+
// User settings (chrome.storage.sync)
184+
"markdocUrl": "http://localhost:4000",
185+
"includeImages": true,
186+
"includeLinks": true,
187+
"includeMetadata": true,
188+
189+
// Temporary import data (chrome.storage.local)
190+
"import_${docId}": {
191+
markdown: string,
192+
timestamp: number,
193+
sourceUrl: string,
194+
sourceTitle: string
195+
}
196+
}
197+
```
198+
199+
## Performance
200+
201+
- **Content Extraction**: Runs once per import (~100-500ms)
202+
- **Markdown Conversion**: Client-side, instant
203+
- **Storage**: Chrome storage API (~10ms read/write)
204+
- **Import**: BlockNote parsing + insertion (~200-500ms)
205+
206+
## Browser Compatibility
207+
208+
| Browser | Status | Notes |
209+
|---------|--------|-------|
210+
| Chrome | ✅ Full | Manifest V3 |
211+
| Edge | ✅ Full | Chromium-based |
212+
| Brave | ✅ Full | Chromium-based |
213+
| Opera | ✅ Full | Chromium-based |
214+
| Firefox | ⚠️ Partial | Needs Manifest V2 modifications |
215+
216+
## Future Enhancements
217+
218+
- [ ] Custom extraction rules per domain
219+
- [ ] Selection-based extraction (import selected text only)
220+
- [ ] Offline queue for when Markdoc is down
221+
- [ ] Direct Y.js update (skip BlockNote conversion)
222+
- [ ] Image upload to S3/CDN (currently just references)
223+
- [ ] PDF export before import
224+
- [ ] Browser action context menu
225+
- [ ] Keyboard shortcut for quick import
226+

chrome-extension/INSTALL.md

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Installation Guide
2+
3+
## Quick Start
4+
5+
### 1. Generate Icons
6+
7+
Open `generate-icons.html` in your browser:
8+
9+
```bash
10+
open chrome-extension/generate-icons.html
11+
```
12+
13+
Click "Download All Icons" and move the downloaded PNG files to the `icons/` folder.
14+
15+
### 2. Load Extension in Chrome
16+
17+
1. Open Chrome and navigate to `chrome://extensions/`
18+
2. Enable "Developer mode" (toggle in top right)
19+
3. Click "Load unpacked"
20+
4. Select the `chrome-extension` folder
21+
5. The extension icon should appear in your toolbar
22+
23+
### 3. Configure Markdoc URL
24+
25+
1. Click the extension icon
26+
2. Set your Markdoc URL:
27+
- Development: `http://localhost:4000`
28+
- Production: `https://your-markdoc-domain.com`
29+
3. Settings are automatically saved
30+
31+
## Usage
32+
33+
### Import a Webpage
34+
35+
1. Navigate to any webpage you want to import
36+
2. Click the extension icon
37+
3. Choose options (images, links, metadata)
38+
4. Click "Import" button
39+
5. The page opens in Markdoc with the content imported
40+
41+
### Copy Markdown Only
42+
43+
1. Click the extension icon
44+
2. Choose your options
45+
3. Click "Copy" button
46+
4. Markdown is copied to clipboard
47+
48+
## Verify Integration
49+
50+
Make sure your Markdoc app is running:
51+
52+
```bash
53+
cd frontend
54+
npm run dev
55+
```
56+
57+
The import feature requires:
58+
- Frontend running (React app)
59+
- Backend running (Phoenix server)
60+
- Import bridge initialized (already added to App.tsx)
61+
62+
## Troubleshooting
63+
64+
### Extension not loading
65+
- Check that all files are present in chrome-extension folder
66+
- Verify icons are in the icons/ subfolder
67+
- Check Chrome console for errors
68+
69+
### Import not working
70+
- Verify Markdoc URL is correct and app is running
71+
- Open browser console (F12) and check for errors
72+
- Make sure the URL parameter `?import=true` is present
73+
74+
### Content extraction issues
75+
- Some websites may block content extraction
76+
- Try adjusting content selectors in popup.js
77+
- Check browser console for specific errors
78+
79+
## Development
80+
81+
### Testing Changes
82+
83+
1. Make changes to extension files
84+
2. Go to `chrome://extensions/`
85+
3. Click refresh icon on your extension
86+
4. Test on a webpage
87+
88+
### Debugging
89+
90+
**Popup:**
91+
- Right-click extension icon → "Inspect popup"
92+
93+
**Background Script:**
94+
- Go to chrome://extensions/
95+
- Click "Inspect views: service worker"
96+
97+
**Content Script:**
98+
- Open DevTools on any page
99+
- Check console for messages
100+
101+
## Next Steps
102+
103+
- Customize icon design in generate-icons.html
104+
- Adjust content extraction selectors in popup.js
105+
- Add custom parsing rules for specific websites
106+
- Publish to Chrome Web Store (optional)
107+

0 commit comments

Comments
 (0)