-
Notifications
You must be signed in to change notification settings - Fork 1
feat: add clipboard, image download, and text selection support #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Claude finished @gupsammy's task —— View job PR Review Complete ✅I've reviewed this PR with a focus on critical issues that would break functionality or prevent Chrome Web Store approval. Checklist:
Issues FoundI found 1 critical bug that will crash the extension and 2 issues worth addressing: 🔴 CRITICAL: Missing script injection in popup.js (line 99)The popup button doesn't inject 🟡 Function duplication (content-script.js line 7)
🟡 Listener leak risk (background.js line 129)Download listeners may not be cleaned up properly if timeouts occur. Consider more robust cleanup. Overall AssessmentThe architecture looks solid for a Manifest V3 extension:
Recommendation: Fix the critical popup.js injection bug, then this is good to ship. The other issues are minor quality improvements. |
| "lib/turndown.js", | ||
| "lib/turndown-plugin-gfm.js", | ||
| "lib/ezycopy.js", | ||
| "content-script.js", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing lib/platform.js injection
The popup button click doesn't inject lib/platform.js, but the content-script.js uses functions from it (like rewriteImagePaths). This will cause a crash when using the popup button.
| "content-script.js", | |
| files: [ | |
| "lib/readability.js", | |
| "lib/turndown.js", | |
| "lib/turndown-plugin-gfm.js", | |
| "lib/ezycopy.js", | |
| "lib/platform.js", | |
| "content-script.js", | |
| ], |
content-script.js
Outdated
| /** | ||
| * Rewrite image URLs in markdown with local file paths | ||
| */ | ||
| function rewriteImagePaths(markdown, urlToPathMap) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function is duplicated
rewriteImagePaths() is defined here AND in lib/platform.js (lines 89-102). Since the platform.js version is injected, this duplicate will override it. Either remove this duplicate or don't inject platform.js.
background.js
Outdated
| chrome.downloads.onChanged.addListener(listener); | ||
|
|
||
| // Timeout after 30 seconds | ||
| setTimeout(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential listener leak
If downloads are interrupted or timeout happens, listeners may remain attached. Consider storing listener refs and cleaning them up properly, or use { once: true } pattern where possible.
|
@claude plan and resolve all. |
|
Claude finished @gupsammy's task —— View job Issues Resolved ✅All three issues from my previous review have been fixed and pushed to the PR branch. Task List:
Changes Made🔴 Fixed Critical Bug: popup.js:99Added files: [
"lib/readability.js",
"lib/turndown.js",
"lib/turndown-plugin-gfm.js",
"lib/ezycopy.js",
"lib/platform.js", // ← Added
"content-script.js",
],🟡 Fixed Function Duplication: content-script.js:7Removed the duplicate 🟡 Fixed Listener Leak Risk: background.js:129Improved cleanup by clearing the timeout when downloads complete or are interrupted. This prevents memory leaks if timeouts occur. let timeoutId = null;
const listener = (delta) => {
if (delta.state && delta.state.current === 'complete') {
clearTimeout(timeoutId); // ← Added
chrome.downloads.onChanged.removeListener(listener);
// ...
}
// ...
};
timeoutId = setTimeout(() => { /* ... */ }, 30000);Testing RecommendationThe critical bug fix ensures both trigger methods (popup button and right-click menu) inject the same scripts. Please test:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
background.js
Outdated
| const DEFAULT_SETTINGS = { | ||
| copyToClipboard: true, | ||
| downloadMarkdown: false, | ||
| downloadImagesLocally: false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Default disables markdown download by default
The default settings now set downloadMarkdown to false even though the context menu still says “Save as Markdown” and the content-script only writes a file when that flag is true. On a fresh install, using the context menu or popup without first opening the settings will only copy to clipboard and never save a .md, which is a regression from the previous behavior that always saved to disk. Consider enabling markdown downloads by default or updating the UX copy to match the new behavior.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@claude update the ux copy to match the new behaviour
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Claude finished @gupsammy's task —— View job
UX Copy Updated ✅
I've updated the context menu text to match the new default behavior where the extension copies to clipboard by default.
Changes Made
Context menu text (background.js:17):
- ❌ Old: "EzyCopy - Save as Markdown"
- ✅ New: "EzyCopy - Extract Content"
The new text is neutral and accurate for both output modes (clipboard copy and file download), avoiding confusion when downloadMarkdown is disabled by default.
Popup UI labels - No changes needed. The existing toggle labels are already clear:
- "Copy to clipboard" → "Copy markdown to clipboard"
- "Download .md" → "Save markdown file to disk"
- "Download images locally" → "Save images with the markdown file"
Summary
The context menu no longer promises to "Save as Markdown" when it might only copy to clipboard. Users can now configure their preferred output method(s) via the popup toggles, and the context menu works consistently regardless of settings.
Commit: f13b13f
|
Claude finished @gupsammy's task —— View job Final PR Review ✅I've reviewed the latest merge commit and verified all previous fixes remain intact. This PR is ready to ship. Review Checklist
What Changed in Latest MergeThe merge commit Verification CompleteAll three previously identified issues remain fixed:
Security & Quality CheckI performed a comprehensive scan focusing on CRITICAL and HIGH severity issues: Manifest V3 Compliance ✅
Security ✅
Message Passing ✅
Script Injection ✅
API Usage ✅
Architecture AssessmentThe refactoring is well-executed:
No critical or high severity issues found. This extension will function correctly and should pass Chrome Web Store review. |
- Add professional header with inline SVG logo and "EzyCopy" branding - Create separate popup.css with refined color system (#2E7D32 primary green) - Implement pure CSS toggle switch for "Download images locally" feature - Add chrome.storage.local persistence for toggle state across sessions - Restructure popup layout (header, action, status, settings sections) - Update showFeedback() toast notifications with slide animations - Add color-mapped icons (checkmark for success, X for error) to toasts - Improve status display with semantic CSS classes (extracting, success, error, cancelled) - Add "storage" permission to manifest.json for persistent user settings - Use safe DOM methods for toast content to prevent XSS vulnerabilities Design improvements: - 320px popup width with 8px grid spacing system - System fonts for native Chrome feel - Accessible toggle using hidden checkbox + styled label pattern - Smooth animations (0.2s transitions, slide-in/out effects) - Light theme (#FAFAFA background) with professional green accents - Helper text below toggle label for feature description
…er storage
Implement complete image download workflow:
- New platform.js utilities for image handling and path generation
- Background service worker handles image downloads via Chrome downloads API
- Content extraction now collects image metadata (URL, alt text)
- Image URLs in markdown are rewritten to local file paths
- Images organized in EzyCopy/images/{page-subfolder}/ structure
- Added settings support for downloadImagesLocally toggle
- Updated manifest permissions to include downloads
The feature maintains backward compatibility - users can keep the
existing remote URL behavior with a toggle in settings.
…down save Replace the browser's file picker (showSaveFilePicker) with direct background service worker handling to save markdown files to Downloads/EzyCopy folder. This simplifies the save flow and provides consistent file organization for both image and non-image download modes. - Update content-script.js to send downloadMarkdown message to background - Update popup.js with same refactored save pattern - Remove try-catch for AbortError as picker is no longer used - Standardize success message to 'Saved to Downloads/EzyCopy!'
…t modes - Add copyToClipboard and downloadMarkdown settings to control output destination - Enforce at least one output method is active to prevent disabling all outputs - Simplify popup UI: remove header, make hero button larger, improve button styling - Nested image download toggle only visible when markdown download is enabled - Settings immediately persisted to storage and UI synced on toggle changes
- Add getSelectionHtml() to detect and extract selected text - Both extractContent() and extractContentWithImages() now check for selection first - Selected text converted to markdown with page title and source link - Return isSelection flag to indicate if extraction was from selection - Selection extraction is tried before full-page Readability extraction
- Unify clipboard and markdown file save in single code path - Add buildSuccessMessage() to generate contextual feedback - Extract content once, then conditionally copy/save based on settings - Show progress toast for image downloads (blue spinner icon) - Auto-dismiss success toasts after 3 seconds, keep progress toasts visible - Remove duplicate image rewriting logic (now only in content-script) - Support isSelection flag from extraction functions for personalized messages
… improve cleanup - Add lib/platform.js to popup.js injection list (fixes missing rewriteImagePaths) - Remove duplicate rewriteImagePaths() from content-script.js (use platform.js version) - Improve listener cleanup in background.js with clearTimeout Co-authored-by: Samarth Gupta <[email protected]>
Changed context menu from 'Save as Markdown' to 'Extract Content' to accurately reflect that the extension now copies to clipboard by default (downloadMarkdown: false). The new text is neutral and works for both clipboard and file download modes. Co-authored-by: Samarth Gupta <[email protected]>
a74570a to
a68cccf
Compare
|
Claude finished @gupsammy's task —— View job Latest Changes Review ✅I've reviewed the commits since my last review and verified all fixes are intact. Review Checklist
SummaryLatest commits:
Status: Ready to merge ✅ All three issues from my initial review have been resolved:
No new issues found. The extension follows Manifest V3 requirements correctly:
Testing RecommendationBoth trigger methods (popup button + right-click menu) now inject identical scripts. Test both with "Download Images" enabled to verify images download and paths rewrite correctly. |
Refactor content extraction logic to separate concerns: extraction returns structured data (title, body, metadata) and a new formatContent() function handles output-specific formatting (clipboard vs download). Add IIFE wrapper to platform.js to prevent redeclaration. Reorganize settings with experimental section for selective copy and local image downloads. Update UI to reflect new settings hierarchy with conditional visibility for image options. Generated with Claude Code Co-Authored-By: Claude <[email protected]>
|
Claude finished @gupsammy's task —— View job Latest Refactoring Review ✅I've reviewed commit Review Checklist
What Changed in Latest CommitCommit Architecture improvements:
Previous Fixes Verified ✅All three issues from my initial review remain fixed:
Security & Code Quality AssessmentCritical Issues: None ✅ High Severity Issues: None ✅ Code Quality:
Settings Structure: {
copyToClipboard: true,
downloadMarkdown: true,
includeImages: true,
experimental: {
selectiveCopy: false, // NEW location
downloadImagesLocally: false // NEW location
}
}UI Improvements:
Architecture ValidationThe refactoring improves maintainability significantly: Before: extractContent() → returns { content: "# Title\n\nSource...\n\nBody", isSelection }After: extractContent({ selectiveCopy }) → returns { title, body, byline, sourceUrl, html, isSelection }
formatContent(extraction, 'clipboard', settings) → "# Title\n\nBody"
formatContent(extraction, 'download', settings) → "# Title\n\nSource...\n\nBody"This design allows different output targets to format content independently without duplicating extraction logic. Final AssessmentStatus: Ready to merge ✅ This is a high-quality refactoring that:
No issues found - all changes are improvements. The extension is production-ready. |
Summary
Add multiple content extraction modes to EzyCopy extension: copy extracted content to clipboard, download local images with organized storage, and support text selection extraction. Redesigned popup UI with persistent toggle states and improved content-script architecture.
Changes
lib/platform.jsutility module for platform-specific operationsCommits
77b9a90- feat(ui): redesign popup with branding and persistent toggleda33d0d- feat(images): add local image download support with organized subfolder storagee903afd- refactor: replace file picker with background service worker for markdown save4bbe6e9- feat(clipboard): add copy-to-clipboard setting with conditional output modesa1427e0- feat(selection): support text selection extraction14e1bb9- refactor(content-script): consolidate clipboard and file output logicFiles Changed
popup.html- Redesigned UI layout with improved controlspopup.js- Enhanced with persistent settings and toggle state managementpopup.css- New stylesheet with branding and styling (182+ lines)background.js- Service worker with file picker delegation (206+ lines)content-script.js- Refactored with consolidated output modes (203+ lines)lib/ezycopy.js- Extended extraction logic for images and selections (189+ lines)lib/platform.js- New utility module for platform-specific operations (102+ lines)manifest.json- Version bump