Margin Notes System
Relevant source files
The following files were used as context for generating this wiki page:
The Margin Notes System provides an interactive sidebar interface for displaying AI-generated and user-authored annotations. It renders information adjacent to specific text ranges within a document, maintaining visual synchronization through a custom layout engine that prevents card overlap during scrolling and resizing.
The system supports multiple viewing modes, including an Overview mode for structural summaries and a Depth mode for granular, personality-driven provocations. Users interact with these notes through expandable cards that support replies, reactions, and direct editing of content.
Sources: extension/src/content/renderer/margin-notes.ts:1-120, extension/src/content/index.ts:1210-1280
Architecture and Components
The system operates within a closed Shadow DOM to isolate styles from the host page. It uses a MarginNote data structure to track the state, position, and associated DOM elements for every annotation.
Core Data Structures
| Type | Description |
|---|---|
MarginNote | Tracks ID, annotation data, anchor span, viewport position (topPx), dimensions, and side. |
InlinePopover | Represents hover-triggered cards used in Depth and Overview modes. |
ChunkRange | Defines the start, end, and full boundaries for text sections in Overview mode. |
Sources: extension/src/content/renderer/margin-notes.ts:32-75
Component Relationship
The following diagram illustrates the relationship between the rendering engine and the annotation entities.
Layout and Positioning Logic
The system utilizes a custom overlap resolution algorithm to ensure notes remain readable. It converts document-relative coordinates to viewport-relative positions using position: fixed.
Overlap Resolution Flow
When the window scrolls or resizes, the system recomputes positions following these steps:
Key Functions
resolveOverlaps(): Orchestrates sorting and spacing for all visible margin notes.applyPositions(): Calculates the shared leading edge (left margin) and applies final CSS styles to elements.refreshMarginNotePositions(): A lightweight optimized path for scroll events that skips height measurements.
Sources: extension/src/content/renderer/margin-notes.ts:1220-1320
User Interaction and Creation
Users create manual annotations by selecting text, which triggers a Floating Action Button (FAB).
Manual Annotation Flow
Interaction Features
- Replies: Users enter text in the
note-reply-inputto create feedback threads. - Reactions: "Agree" and "I don't think so" buttons toggle mutually exclusive feedback states and update a reaction badge on the note.
- Editing: For manual notes, clicking the body text enters an edit mode with a textarea and save/cancel actions.
- GDocs Integration: In Google Docs, the system uses synthetic fixed-position anchors since standard DOM ranges do not exist on the canvas.
Sources: extension/src/content/renderer/margin-notes.ts:860-980, extension/src/content/index.ts:1040-1100
Display Modes and Personalities
The display logic varies based on the active ViewMode and the selected AI personality.
View Modes
| Mode | Behavior |
|---|---|
overview | Renders structural summaries as margin notes. Highlights entire text chunks. |
depth | Uses inline popovers that appear on hover. Driven by specific AI personalities. |
all | Combines both modes, using popovers for depth and margin cards for overview. |
Sources: extension/src/content/index.ts:1390-1460, backend/config/prompts.json:1-150
Personality Attribution
The header of a margin note displays the author's name. This is resolved via resolveMarginNoteHeaderAuthor:
- AI Notes (Depth): Displays personality names like "Terry", "Jerry", or "Sally".
- AI Notes (Overview): Displays "Overview".
- Manual Notes: Displays the
userDisplayNamefetched from the user's profile.
Sources: extension/src/content/renderer/margin-notes.ts:110-150, extension/src/content/tests/margin-notes.test.ts:30-65
Conclusion
The Margin Notes System serves as the primary consumption interface for Oddity 1, bridging the gap between static text and dynamic AI insights. By combining robust DOM anchoring with a specialized layout engine and flexible viewing modes, it provides a non-intrusive yet accessible way for users to engage with complex documents and their own annotations.
Sources: extension/src/content/renderer/margin-notes.ts:1-100, extension/src/content/index.ts:1-100