-
Notifications
You must be signed in to change notification settings - Fork 82
cf240
[Grida Canvas] Implement cross-window clipboard paste
#372
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
cf240
[Grida Canvas] Implement cross-window clipboard paste
#372
Conversation
Review or Edit in CodeSandboxOpen the branch in Web Editor • VS Code • Insiders |
WalkthroughThe changes implement robust HTML clipboard support for Grida's canvas editor. Clipboard payloads are now encoded as base64 JSON within custom HTML attributes and decoded on paste, allowing for accurate transfer of scene data. This includes updates to the clipboard state structure, reducer logic, new encoding/decoding utilities, tests, and dependency updates. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant EditorUI
participant Clipboard
participant IOClipboard
User->>EditorUI: Copy/Cut
EditorUI->>IOClipboard: encodeClipboardHtml(payload)
IOClipboard-->>EditorUI: HTML string with base64 data
EditorUI->>Clipboard: Write HTML string
User->>EditorUI: Paste
EditorUI->>Clipboard: Read clipboard
Clipboard-->>EditorUI: HTML string
EditorUI->>IOClipboard: decodeClipboardHtml(html)
IOClipboard-->>EditorUI: ClipboardPayload or null
EditorUI->>EditorUI: Insert scene(s) or fallback to text
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (2)
✅ Files skipped from review due to trivial changes (2)
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
6 Skipped Deployments
|
…able-cross-window-copy-paste-functionality
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.
Actionable comments posted: 3
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (7)
editor/grida-canvas-react/provider.tsx
(6 hunks)editor/grida-canvas/index.ts
(1 hunks)editor/grida-canvas/reducers/document.reducer.ts
(1 hunks)editor/package.json
(1 hunks)packages/grida-canvas-io/__tests__/clipboard.test.ts
(1 hunks)packages/grida-canvas-io/index.ts
(1 hunks)packages/grida-canvas-io/package.json
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
packages/grida-canvas-io/__tests__/clipboard.test.ts (1)
packages/grida-canvas-io/index.ts (1)
ClipboardPayload
(12-16)
editor/grida-canvas-react/provider.tsx (2)
editor/grida-canvas-react/use-editor.tsx (1)
useEditorState
(35-47)editor/grida-canvas/reducers/tools/id.ts (1)
nid
(10-15)
🔇 Additional comments (8)
editor/package.json (1)
146-146
:❓ Verification inconclusive
Verify major version update compatibility and security.
The
fast-xml-parser
dependency is being updated from^4.4.0
to^5.2.3
, which is a major version bump that may introduce breaking changes. Ensure this update is compatible with existing code and check for any security advisories.
🏁 Script executed:
#!/bin/bash # Description: Check for security advisories and compatibility issues with fast-xml-parser v5.2.3 # Check if version exists and get release notes curl -s https://api.github.com/repos/NaturalIntelligence/fast-xml-parser/releases | jq '.[] | select(.tag_name | contains("v5.2.3") or contains("5.2.3")) | {tag_name, published_at, body}' # Check for security advisories gh api graphql -f query=' { securityVulnerabilities(first: 10, ecosystem: NPM, package: "fast-xml-parser") { nodes { advisory { summary severity publishedAt } vulnerableVersionRange firstPatchedVersion { identifier } } } }' # Check changelog for breaking changes between v4 and v5 curl -s https://api.github.com/repos/NaturalIntelligence/fast-xml-parser/compare/v4.4.0...v5.2.3 | jq '.status'Length of output: 1617
Review [email protected] bump for compatibility and security.
- Location:
editor/package.json
(line 146, bumped from^4.4.0
to^5.2.3
)- Release status:
5.2.3
is a published npm version and is “ahead” of4.4.0
.- Security: No known advisories affect versions ≥ 4.4.1; all vulnerabilities were patched before v5.
- Action required: v5 contains breaking changes—please review the migration guide (https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/MIGRATION.md) and rerun your XML/HTML clipboard parsing tests to confirm existing code still works as expected.
packages/grida-canvas-io/package.json (1)
6-21
: LGTM! Clean package.json updates for testing infrastructure.The changes properly add:
- Test script for Jest execution
fast-xml-parser
dependency consistent with editor package- Minimal Jest configuration with
ts-jest
preset for TypeScript supportThe formatting and structure are correct.
editor/grida-canvas/index.ts (1)
326-327
: LGTM! Well-documented interface extension for clipboard identification.The addition of
payload_id
as a required string property is well-documented and serves a clear purpose for distinguishing clipboard contents across windows. This enables robust clipboard state management.packages/grida-canvas-io/__tests__/clipboard.test.ts (1)
3-75
: Well-structured test suite with comprehensive coverage.The test suite effectively covers:
- Basic encode/decode functionality
- Browser HTML manipulation scenarios
- Error handling for invalid inputs
Good job on the test implementation!
packages/grida-canvas-io/index.ts (2)
18-23
: Solid implementation of clipboard HTML encoding.The encoding correctly handles UTF-8 conversion and base64 encoding. The use of a custom data attribute with a unique prefix prevents conflicts.
51-73
: Excellent implementation with comprehensive documentation and error handling.The decode function:
- Handles browser HTML manipulation gracefully
- Provides clear JSDoc with examples
- Returns null safely on errors
- Efficiently decodes base64 data
Great work on the implementation!
editor/grida-canvas-react/provider.tsx (2)
1219-1243
: Well-implemented clipboard paste handling with proper fallbacks.The implementation correctly:
- Decodes clipboard HTML data
- Checks payload_id to distinguish between internal and external pastes
- Creates new IDs for inserted nodes using the nid utility
- Falls back to text insertion if decoding fails
Excellent integration!
1312-1325
: Clean implementation of clipboard synchronization.The updated implementation properly uses the new encoding function and handles potential errors gracefully.
@@ -94,6 +94,7 @@ export default function documentReducer<S extends editor.state.IEditorState>( | |||
return produce(state, (draft) => { | |||
// [copy] | |||
draft.user_clipboard = { | |||
payload_id: crypto.randomUUID(), |
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.
💡 Verification agent
🧩 Analysis chain
Verify browser compatibility for crypto.randomUUID().
The implementation correctly adds unique payload IDs to clipboard data. However, crypto.randomUUID()
requires browser support and may not be available in all environments (e.g., older browsers, some Node.js contexts).
Consider checking browser compatibility or providing a fallback:
- payload_id: crypto.randomUUID(),
+ payload_id: crypto.randomUUID?.() || `${Date.now()}-${Math.random()}`,
Let's verify the current browser support:
🏁 Script executed:
#!/bin/bash
# Description: Check crypto.randomUUID() usage in the codebase and verify it's consistently used
# Search for other uses of crypto.randomUUID in the codebase
rg -A 2 -B 2 "crypto\.randomUUID"
# Search for alternative UUID generation methods
rg -A 2 -B 2 "randomUUID|uuid|UUID"
Length of output: 68119
Add a fallback for crypto.randomUUID() using the existing uuid library
To avoid runtime errors in environments where crypto.randomUUID is unavailable (e.g. older Safari or non-Web Crypto contexts), fall back to the project’s uuid package:
• File: editor/grida-canvas/reducers/document.reducer.ts
Line: 97
// At top of file, alongside other imports
+ import { v4 as uuidv4 } from 'uuid';
…
- payload_id: crypto.randomUUID(),
+ payload_id: crypto.randomUUID?.() ?? uuidv4(),
This ensures a stable UUID in all supported runtimes.
🤖 Prompt for AI Agents
In editor/grida-canvas/reducers/document.reducer.ts at line 97, the use of
crypto.randomUUID() may cause runtime errors in environments lacking support.
Modify the code to check if crypto.randomUUID is available; if not, use the
existing uuid library's UUID generation function as a fallback. This ensures
consistent UUID generation across all supported environments.
const parser = new XMLParser({ | ||
ignoreAttributes: (key) => !key.startsWith(__data_grida_io_prefix), | ||
attributeNamePrefix: "@", | ||
unpairedTags: ["meta"], |
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.
🛠️ Refactor suggestion
Consider adding more unpaired tags to XMLParser configuration.
Browsers might add other self-closing tags when manipulating clipboard content. Consider expanding the unpaired tags list to prevent parsing errors.
- unpairedTags: ["meta"],
+ unpairedTags: ["meta", "link", "br", "hr", "img", "input", "area", "base", "col", "embed", "source", "track", "wbr"],
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
unpairedTags: ["meta"], | |
unpairedTags: [ | |
"meta", | |
"link", | |
"br", | |
"hr", | |
"img", | |
"input", | |
"area", | |
"base", | |
"col", | |
"embed", | |
"source", | |
"track", | |
"wbr" | |
], |
🤖 Prompt for AI Agents
In packages/grida-canvas-io/index.ts at line 56, the XMLParser configuration
currently includes only "meta" as an unpaired tag. To prevent parsing errors
caused by browsers adding other self-closing tags in clipboard content, expand
the unpairedTags array to include additional common self-closing tags such as
"img", "br", "hr", "input", and "link". Update the configuration to cover these
tags to improve robustness.
cf240
[Grida Canvas] Implement cross-window clipboard paste
Implemented IO Clipboard, for cross document, cross editor, cross window copy-paste of grida documents
day-240-grida-canvas-io-cross-window-clipboard.mp4
use https://madebyevan.com/clipboard-test/ for testing payload
Limitations
This does not handle copy / paste of assets.
Summary
text/html
clipboard payload on paste eventspayload_id
to clipboard stateTesting
pnpm turbo test
Summary by CodeRabbit