"Track 3 wrote. Track 4 read. Track 7 closes with edit and delete — the last two letters of CRUD — and the Undo toast that turns 'I just nuked my clip' into 'I'll get it back in 5 seconds.' By the end ClipDeck has the full lifecycle."
What Inline Edit Means
Click a clip's text in the side panel; it becomes editable in place. Type. Press Enter to save, Escape to revert. No modal, no tab navigation, no separate form. The clip's text and title both support inline edit; the URL and timestamp are immutable (they're provenance, not user-owned data).
Two competing approaches:
- contenteditable — set
contenteditable="true"on the text element. Native browser editing. Pros: free formatting controls (Cmd+B for bold etc), good keyboard handling. Cons: handles HTML, which means you have to sanitize on save. - swap to textarea — replace the rendered text with a
<textarea>on click. Pros: plain text always, predictable. Cons: more code, no formatting, focus management is manual.
ClipDeck v1 ships textarea — plain text is the schema, and the simplicity pays for itself. v2 could add contenteditable for rich clips.
The Edit Flow
- User clicks the clip's text.
- Click handler replaces the
<p>with a<textarea>containing the current text, focuses it, selects all. - Enter (without Shift) commits; Escape reverts; click outside also reverts.
- On commit, the SW writes the updated clip back to storage (replacing the same id in the clips array). storage.onChanged fires, the row re-renders with the new text.
The same shape for title — click → input → Enter/Escape. Title is a single-line input rather than a textarea.
The Delete Flow With Undo
Inline trash icon on each row. Click → row fades out, gets replaced briefly with an Undo toast ("Clip deleted. Undo"). Toast persists for 5 seconds; if the user clicks Undo, the clip restores. If the timeout elapses, the clip is gone for good (or scheduled for purge — see below).
Two ways to implement the 5-second window:
- Soft delete — flag the clip as
deletedAt: timestampinstead of removing. The render filters them out. After 5 seconds, the actual remove call runs. Undo flipsdeletedAtback to null. - Stash and restore — actually remove from clips, hold the removed clip in memory; on Undo, push it back. If timeout passes, drop it from memory.
Soft delete is more robust against SW eviction (the in-memory stash dies with the worker). ClipDeck v1 uses soft delete and runs a periodic cleanup alarm that prunes anything deletedAt < now - 5s.
The Multi-Select Variant
Once edit and delete exist, the next obvious feature is multi-select: "delete these 12 clips at once." The side panel needs:
- Checkbox column on each row, hidden until the user enters select mode.
- A 'Select' button that toggles select mode (rows now show checkboxes; click row toggles checkbox).
- A bulk-action bar at the top when any are selected ("3 selected | Delete | Export | Tag").
Same Undo pattern: bulk delete soft-flags all selected clips with the same deletedAt; one Undo button restores all. ClipDeck v1 ships single-row delete; multi-select goes to v1.1.
The Edit Race
A subtle bug: user opens edit mode on a clip. Storage.onChanged fires from another window (or another tab adding a clip). The render runs, blowing away the textarea mid-edit. Defense: maintain a editingId in panel.js memory; skip re-rendering rows where editingId === clip.id during the onChanged-triggered render.
This is a common gotcha across any list with inline edit and live updates. ClipDeck's storage layer is shared across popup, panel, content scripts — any of them could trigger a render at any time.
Wrapping Track 7
Seven tracks complete:
- MV3 foundations, service worker, content scripts, side panel, action+popup, permissions, DOM tools.
- Full CRUD: Create (Track 3), Read (Track 4), Update + Delete (this lesson).
- Triggers: floating button, keyboard, popup, context menu, omnibox.
- Surface allocation: popup, side panel, options page placeholder.
- Per-tab pause, just-in-time permissions, Readability, screenshots, React-friendly fill, preview-and-confirm.
Track 8 is packaging — the build system, the .crx versus unpacked, the Chrome Web Store submission, the icons and the privacy policy and everything else that turns the working folder into something other people can install.