一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
670 行
47 KiB
JSON
670 行
47 KiB
JSON
{
|
||
"issue": {
|
||
"url": "https://api.github.com/repos/laurent22/joplin/issues/15113",
|
||
"repository_url": "https://api.github.com/repos/laurent22/joplin",
|
||
"labels_url": "https://api.github.com/repos/laurent22/joplin/issues/15113/labels{/name}",
|
||
"comments_url": "https://api.github.com/repos/laurent22/joplin/issues/15113/comments",
|
||
"events_url": "https://api.github.com/repos/laurent22/joplin/issues/15113/events",
|
||
"html_url": "https://github.com/laurent22/joplin/pull/15113",
|
||
"id": 4269632112,
|
||
"node_id": "PR_kwDOBLftOs7Sq-8J",
|
||
"number": 15113,
|
||
"title": "Desktop: Fixes #14979: Fixed copying and cutting table columns in Rich Text editor",
|
||
"user": {
|
||
"login": "bhaktideshmukh",
|
||
"id": 78796264,
|
||
"node_id": "MDQ6VXNlcjc4Nzk2MjY0",
|
||
"avatar_url": "https://avatars.githubusercontent.com/u/78796264?v=4",
|
||
"gravatar_id": "",
|
||
"url": "https://api.github.com/users/bhaktideshmukh",
|
||
"html_url": "https://github.com/bhaktideshmukh",
|
||
"followers_url": "https://api.github.com/users/bhaktideshmukh/followers",
|
||
"following_url": "https://api.github.com/users/bhaktideshmukh/following{/other_user}",
|
||
"gists_url": "https://api.github.com/users/bhaktideshmukh/gists{/gist_id}",
|
||
"starred_url": "https://api.github.com/users/bhaktideshmukh/starred{/owner}{/repo}",
|
||
"subscriptions_url": "https://api.github.com/users/bhaktideshmukh/subscriptions",
|
||
"organizations_url": "https://api.github.com/users/bhaktideshmukh/orgs",
|
||
"repos_url": "https://api.github.com/users/bhaktideshmukh/repos",
|
||
"events_url": "https://api.github.com/users/bhaktideshmukh/events{/privacy}",
|
||
"received_events_url": "https://api.github.com/users/bhaktideshmukh/received_events",
|
||
"type": "User",
|
||
"user_view_type": "public",
|
||
"site_admin": false
|
||
},
|
||
"labels": [
|
||
{
|
||
"id": 519700741,
|
||
"node_id": "MDU6TGFiZWw1MTk3MDA3NDE=",
|
||
"url": "https://api.github.com/repos/laurent22/joplin/labels/bug",
|
||
"name": "bug",
|
||
"color": "cf353b",
|
||
"default": true,
|
||
"description": "It's a bug"
|
||
},
|
||
{
|
||
"id": 1080341216,
|
||
"node_id": "MDU6TGFiZWwxMDgwMzQxMjE2",
|
||
"url": "https://api.github.com/repos/laurent22/joplin/labels/desktop",
|
||
"name": "desktop",
|
||
"color": "ffc274",
|
||
"default": false,
|
||
"description": "All desktop platforms"
|
||
},
|
||
{
|
||
"id": 1366672371,
|
||
"node_id": "MDU6TGFiZWwxMzY2NjcyMzcx",
|
||
"url": "https://api.github.com/repos/laurent22/joplin/labels/editor",
|
||
"name": "editor",
|
||
"color": "91ca55",
|
||
"default": false,
|
||
"description": ""
|
||
}
|
||
],
|
||
"state": "closed",
|
||
"locked": false,
|
||
"assignees": [],
|
||
"milestone": null,
|
||
"comments": 9,
|
||
"created_at": "2026-04-15T14:28:57Z",
|
||
"updated_at": "2026-04-30T18:55:18Z",
|
||
"closed_at": "2026-04-30T15:26:51Z",
|
||
"assignee": null,
|
||
"author_association": "NONE",
|
||
"active_lock_reason": null,
|
||
"draft": false,
|
||
"pull_request": {
|
||
"url": "https://api.github.com/repos/laurent22/joplin/pulls/15113",
|
||
"html_url": "https://github.com/laurent22/joplin/pull/15113",
|
||
"diff_url": "https://github.com/laurent22/joplin/pull/15113.diff",
|
||
"patch_url": "https://github.com/laurent22/joplin/pull/15113.patch",
|
||
"merged_at": null
|
||
},
|
||
"body": "# Problem\r\n\r\nPreviously, when working in the Rich Text editor, copying, cutting, or pasting isolated table columns behaved incorrectly\r\n\r\n- Copying & Cutting: Successfully copied the data, but when attempting to delete the source selection, it only deleted the very first \"anchor\" cell and left the rest of the column completely untouched.\r\n- Pasting: Pasting a copied column directly dumped the entire structure inside the single target cell instead of correctly splicing the columns sideways.\r\n\r\n# Solution\r\n\r\n- This PR fixes issues with cutting, copying, and pasting table columns by letting the TinyMCE Table Plugin handle things naturally instead of forcing strict formatting rules.\r\n\r\n- For cut and copy, when table cells are selected, we skip the custom override so the plugin can properly delete or copy full columns. We still capture the result afterward so Joplin can use it.\r\n\r\n- For paste, if table content is detected, we avoid the usual Markdown conversion and instead use TinyMCE’s native paste, which keeps the column structure and spacing intact while still processing images correctly.\r\n\r\n\r\nFixes #14979 .\r\n\r\n\r\n# Testing\r\n\r\n## Existing Behavior\r\n\r\nhttps://github.com/user-attachments/assets/187f9940-35dc-4dde-b92a-ca03854ffad9\r\n\r\n\r\n## Current Behavior\r\n\r\nhttps://github.com/user-attachments/assets/80ed88cc-779a-44d2-b046-e4787b3fb289\r\n\r\n\r\n",
|
||
"closed_by": {
|
||
"login": "laurent22",
|
||
"id": 1285584,
|
||
"node_id": "MDQ6VXNlcjEyODU1ODQ=",
|
||
"avatar_url": "https://avatars.githubusercontent.com/u/1285584?v=4",
|
||
"gravatar_id": "",
|
||
"url": "https://api.github.com/users/laurent22",
|
||
"html_url": "https://github.com/laurent22",
|
||
"followers_url": "https://api.github.com/users/laurent22/followers",
|
||
"following_url": "https://api.github.com/users/laurent22/following{/other_user}",
|
||
"gists_url": "https://api.github.com/users/laurent22/gists{/gist_id}",
|
||
"starred_url": "https://api.github.com/users/laurent22/starred{/owner}{/repo}",
|
||
"subscriptions_url": "https://api.github.com/users/laurent22/subscriptions",
|
||
"organizations_url": "https://api.github.com/users/laurent22/orgs",
|
||
"repos_url": "https://api.github.com/users/laurent22/repos",
|
||
"events_url": "https://api.github.com/users/laurent22/events{/privacy}",
|
||
"received_events_url": "https://api.github.com/users/laurent22/received_events",
|
||
"type": "User",
|
||
"user_view_type": "public",
|
||
"site_admin": false
|
||
},
|
||
"reactions": {
|
||
"url": "https://api.github.com/repos/laurent22/joplin/issues/15113/reactions",
|
||
"total_count": 0,
|
||
"+1": 0,
|
||
"-1": 0,
|
||
"laugh": 0,
|
||
"hooray": 0,
|
||
"confused": 0,
|
||
"heart": 0,
|
||
"rocket": 0,
|
||
"eyes": 0
|
||
},
|
||
"timeline_url": "https://api.github.com/repos/laurent22/joplin/issues/15113/timeline",
|
||
"performed_via_github_app": null,
|
||
"state_reason": null
|
||
},
|
||
"comments": [
|
||
{
|
||
"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4252914271",
|
||
"html_url": "https://github.com/laurent22/joplin/pull/15113#issuecomment-4252914271",
|
||
"issue_url": "https://api.github.com/repos/laurent22/joplin/issues/15113",
|
||
"id": 4252914271,
|
||
"node_id": "IC_kwDOBLftOs79flJf",
|
||
"user": {
|
||
"login": "github-actions[bot]",
|
||
"id": 41898282,
|
||
"node_id": "MDM6Qm90NDE4OTgyODI=",
|
||
"avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4",
|
||
"gravatar_id": "",
|
||
"url": "https://api.github.com/users/github-actions%5Bbot%5D",
|
||
"html_url": "https://github.com/apps/github-actions",
|
||
"followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers",
|
||
"following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}",
|
||
"gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}",
|
||
"starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}",
|
||
"subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions",
|
||
"organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs",
|
||
"repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos",
|
||
"events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}",
|
||
"received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events",
|
||
"type": "Bot",
|
||
"user_view_type": "public",
|
||
"site_admin": false
|
||
},
|
||
"created_at": "2026-04-15T14:29:12Z",
|
||
"updated_at": "2026-04-30T18:55:19Z",
|
||
"body": "All contributors have signed the CLA ✍️ ✅<br/><sub>Posted by the ****CLA Assistant Lite bot****.</sub>",
|
||
"author_association": "CONTRIBUTOR",
|
||
"reactions": {
|
||
"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4252914271/reactions",
|
||
"total_count": 0,
|
||
"+1": 0,
|
||
"-1": 0,
|
||
"laugh": 0,
|
||
"hooray": 0,
|
||
"confused": 0,
|
||
"heart": 0,
|
||
"rocket": 0,
|
||
"eyes": 0
|
||
},
|
||
"performed_via_github_app": {
|
||
"id": 15368,
|
||
"client_id": "Iv1.05c79e9ad1f6bdfa",
|
||
"slug": "github-actions",
|
||
"node_id": "MDM6QXBwMTUzNjg=",
|
||
"owner": {
|
||
"login": "github",
|
||
"id": 9919,
|
||
"node_id": "MDEyOk9yZ2FuaXphdGlvbjk5MTk=",
|
||
"avatar_url": "https://avatars.githubusercontent.com/u/9919?v=4",
|
||
"gravatar_id": "",
|
||
"url": "https://api.github.com/users/github",
|
||
"html_url": "https://github.com/github",
|
||
"followers_url": "https://api.github.com/users/github/followers",
|
||
"following_url": "https://api.github.com/users/github/following{/other_user}",
|
||
"gists_url": "https://api.github.com/users/github/gists{/gist_id}",
|
||
"starred_url": "https://api.github.com/users/github/starred{/owner}{/repo}",
|
||
"subscriptions_url": "https://api.github.com/users/github/subscriptions",
|
||
"organizations_url": "https://api.github.com/users/github/orgs",
|
||
"repos_url": "https://api.github.com/users/github/repos",
|
||
"events_url": "https://api.github.com/users/github/events{/privacy}",
|
||
"received_events_url": "https://api.github.com/users/github/received_events",
|
||
"type": "Organization",
|
||
"user_view_type": "public",
|
||
"site_admin": false
|
||
},
|
||
"name": "GitHub Actions",
|
||
"description": "Automate your workflow from idea to production",
|
||
"external_url": "https://help.github.com/en/actions",
|
||
"html_url": "https://github.com/apps/github-actions",
|
||
"created_at": "2018-07-30T09:30:17Z",
|
||
"updated_at": "2026-05-05T14:51:38Z",
|
||
"permissions": {
|
||
"actions": "write",
|
||
"administration": "read",
|
||
"artifact_metadata": "write",
|
||
"attestations": "write",
|
||
"checks": "write",
|
||
"code_quality": "write",
|
||
"contents": "write",
|
||
"copilot_requests": "write",
|
||
"deployments": "write",
|
||
"discussions": "write",
|
||
"issues": "write",
|
||
"merge_queues": "write",
|
||
"metadata": "read",
|
||
"models": "read",
|
||
"packages": "write",
|
||
"pages": "write",
|
||
"pull_requests": "write",
|
||
"repository_hooks": "write",
|
||
"repository_projects": "write",
|
||
"security_events": "write",
|
||
"statuses": "write",
|
||
"vulnerability_alerts": "read"
|
||
},
|
||
"events": [
|
||
"branch_protection_rule",
|
||
"check_run",
|
||
"check_suite",
|
||
"create",
|
||
"delete",
|
||
"deployment",
|
||
"deployment_status",
|
||
"discussion",
|
||
"discussion_comment",
|
||
"fork",
|
||
"gollum",
|
||
"issues",
|
||
"issue_comment",
|
||
"label",
|
||
"merge_group",
|
||
"milestone",
|
||
"page_build",
|
||
"public",
|
||
"pull_request",
|
||
"pull_request_review",
|
||
"pull_request_review_comment",
|
||
"push",
|
||
"registry_package",
|
||
"release",
|
||
"repository",
|
||
"repository_dispatch",
|
||
"status",
|
||
"watch",
|
||
"workflow_dispatch",
|
||
"workflow_run"
|
||
]
|
||
}
|
||
},
|
||
{
|
||
"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4252915757",
|
||
"html_url": "https://github.com/laurent22/joplin/pull/15113#issuecomment-4252915757",
|
||
"issue_url": "https://api.github.com/repos/laurent22/joplin/issues/15113",
|
||
"id": 4252915757,
|
||
"node_id": "IC_kwDOBLftOs79flgt",
|
||
"user": {
|
||
"login": "coderabbitai[bot]",
|
||
"id": 136622811,
|
||
"node_id": "BOT_kgDOCCSy2w",
|
||
"avatar_url": "https://avatars.githubusercontent.com/in/347564?v=4",
|
||
"gravatar_id": "",
|
||
"url": "https://api.github.com/users/coderabbitai%5Bbot%5D",
|
||
"html_url": "https://github.com/apps/coderabbitai",
|
||
"followers_url": "https://api.github.com/users/coderabbitai%5Bbot%5D/followers",
|
||
"following_url": "https://api.github.com/users/coderabbitai%5Bbot%5D/following{/other_user}",
|
||
"gists_url": "https://api.github.com/users/coderabbitai%5Bbot%5D/gists{/gist_id}",
|
||
"starred_url": "https://api.github.com/users/coderabbitai%5Bbot%5D/starred{/owner}{/repo}",
|
||
"subscriptions_url": "https://api.github.com/users/coderabbitai%5Bbot%5D/subscriptions",
|
||
"organizations_url": "https://api.github.com/users/coderabbitai%5Bbot%5D/orgs",
|
||
"repos_url": "https://api.github.com/users/coderabbitai%5Bbot%5D/repos",
|
||
"events_url": "https://api.github.com/users/coderabbitai%5Bbot%5D/events{/privacy}",
|
||
"received_events_url": "https://api.github.com/users/coderabbitai%5Bbot%5D/received_events",
|
||
"type": "Bot",
|
||
"user_view_type": "public",
|
||
"site_admin": false
|
||
},
|
||
"created_at": "2026-04-15T14:29:24Z",
|
||
"updated_at": "2026-04-15T14:33:45Z",
|
||
"body": "<!-- This is an auto-generated comment: summarize by coderabbit.ai -->\n<!-- walkthrough_start -->\n\n<details>\n<summary>📝 Walkthrough</summary>\n\n## Walkthrough\n\nFixes table column and multi-cell selection copy-cut operations in the rich text editor by detecting table context selections and routing them through native browser clipboard commands instead of standard content conversion handlers.\n\n## Changes\n\n|Cohort / File(s)|Summary|\n|---|---|\n|**Table Selection Detection** <br> `packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useContextMenu.ts`, `packages/app-desktop/gui/NoteEditor/utils/contextMenu.ts`|Updated to identify multi-cell or multi-row table selections and emit `'table-selected'` marker; context menu actions now route these selections to native `execCommand('copy'/'cut')` operations.|\n|**TinyMCE Editor Integration** <br> `packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx`|Enhanced copy and cut handlers to detect table context and schedule async clipboard reading for multi-cell selections; improved paste handling to bypass Markdown conversion when pasting table content within table boundaries; TypeScript spacing adjustments for type annotations.|\n\n## Suggested labels\n\n`bug`, `desktop`, `editor`\n\n</details>\n\n<!-- walkthrough_end -->\n\n\n<!-- pre_merge_checks_walkthrough_start -->\n\n---\n\n<!-- pre_merge_checks_override_start -->\n> [!IMPORTANT]\n> ## Pre-merge checks failed\n> \n> Please resolve all errors before merging. Addressing warnings is optional.\n<!-- pre_merge_checks_override_end -->\n\n### ❌ Failed checks (1 error, 1 warning)\n\n| Check name | Status | Explanation | Resolution |\n| :-----------------------------------: | :--------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Pr Description Must Follow Guidelines | ❌ Error | PR description includes problem statement and solution explanation but lacks a dedicated Test Plan or verification steps section documenting reproduction steps and cross-platform validation. | Add a Test Plan section documenting: step-by-step reproduction instructions, expected behaviour after fix, cross-platform testing confirmation (Windows, macOS, Linux), and edge case verification. |\n| Docstring Coverage | ⚠️ Warning | Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. | Write docstrings for the functions missing them to satisfy the coverage threshold. |\n\n<details>\n<summary>✅ Passed checks (4 passed)</summary>\n\n| Check name | Status | Explanation |\n| :------------------------: | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Title check | ✅ Passed | The title clearly summarizes the main change: fixing copying and cutting of table columns in the Rich Text editor, with specific issue reference. |\n| Description check | ✅ Passed | The description is directly related to the changeset, providing clear context on the problem, solution, and testing evidence for table column copy/cut/paste functionality. |\n| Linked Issues check | ✅ Passed | The code changes comprehensively address the requirements in `#14979`: handling multi-cell table selection for copy/cut operations and detecting table content for paste operations to preserve column structure. |\n| Out of Scope Changes check | ✅ Passed | All changes are directly related to fixing table column operations; minor TypeScript formatting adjustments are incidental to the core functionality improvements. |\n\n</details>\n\n<!-- pre_merge_checks_walkthrough_end -->\n\n<!-- finishing_touch_checkbox_start -->\n\n<details>\n<summary>✨ Finishing Touches</summary>\n\n<details>\n<summary>🧪 Generate unit tests (beta)</summary>\n\n- [ ] <!-- {\"checkboxId\": \"f47ac10b-58cc-4372-a567-0e02b2c3d479\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} --> Create PR with unit tests\n\n</details>\n\n</details>\n\n<!-- finishing_touch_checkbox_end -->\n\n<!-- tips_start -->\n\n---\n\nThanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=laurent22/joplin&utm_content=15113)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.\n\n<details>\n<summary>❤️ Share</summary>\n\n- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)\n- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)\n- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)\n- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)\n\n</details>\n\n<sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub>\n\n<!-- tips_end -->\n\n<!-- internal state start -->\n\n\n<!-- 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 -->\n\n<!-- internal state end -->",
|
||
"author_association": "CONTRIBUTOR",
|
||
"reactions": {
|
||
"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4252915757/reactions",
|
||
"total_count": 0,
|
||
"+1": 0,
|
||
"-1": 0,
|
||
"laugh": 0,
|
||
"hooray": 0,
|
||
"confused": 0,
|
||
"heart": 0,
|
||
"rocket": 0,
|
||
"eyes": 0
|
||
},
|
||
"performed_via_github_app": {
|
||
"id": 347564,
|
||
"client_id": "Iv1.6aaafe4fe882736b",
|
||
"slug": "coderabbitai",
|
||
"node_id": "A_kwHOB96YWc4ABU2s",
|
||
"owner": {
|
||
"login": "coderabbitai",
|
||
"id": 132028505,
|
||
"node_id": "O_kgDOB96YWQ",
|
||
"avatar_url": "https://avatars.githubusercontent.com/u/132028505?v=4",
|
||
"gravatar_id": "",
|
||
"url": "https://api.github.com/users/coderabbitai",
|
||
"html_url": "https://github.com/coderabbitai",
|
||
"followers_url": "https://api.github.com/users/coderabbitai/followers",
|
||
"following_url": "https://api.github.com/users/coderabbitai/following{/other_user}",
|
||
"gists_url": "https://api.github.com/users/coderabbitai/gists{/gist_id}",
|
||
"starred_url": "https://api.github.com/users/coderabbitai/starred{/owner}{/repo}",
|
||
"subscriptions_url": "https://api.github.com/users/coderabbitai/subscriptions",
|
||
"organizations_url": "https://api.github.com/users/coderabbitai/orgs",
|
||
"repos_url": "https://api.github.com/users/coderabbitai/repos",
|
||
"events_url": "https://api.github.com/users/coderabbitai/events{/privacy}",
|
||
"received_events_url": "https://api.github.com/users/coderabbitai/received_events",
|
||
"type": "Organization",
|
||
"user_view_type": "public",
|
||
"site_admin": false
|
||
},
|
||
"name": "coderabbitai",
|
||
"description": "# Transforming Code Reviews with AI\r\n\r\n## Features\r\n\r\n**Automated Reviews**: Continuous reviews of the pull requests including incremental commits. \r\n\r\n**Summarization**: Generates high-level summary and a technical walkthrough of the PR changes. \r\n\r\n**Line-by-line review**: Provides line-by-line suggestions committable with one click.\r\n\r\n**Codebase verification**: Verifies the impact on the overall codebase and identifies missing changes.\r\n\r\n**Insights into your code**: Ask any questions on your codebase within the pull request \r\n\r\n**Chat about your code** : Chat with the bot around your code. The more you chat, the smarter it gets.\r\n\r\n**Issue Validation**: Validates the PR against the linked issues and identifies other related issues \r\n\r\n\r\n\r\n",
|
||
"external_url": "https://coderabbit.ai?utm_source=cr_app&utm_medium=github",
|
||
"html_url": "https://github.com/apps/coderabbitai",
|
||
"created_at": "2023-06-14T15:47:27Z",
|
||
"updated_at": "2026-03-14T07:58:44Z",
|
||
"permissions": {
|
||
"actions": "read",
|
||
"checks": "write",
|
||
"contents": "write",
|
||
"discussions": "read",
|
||
"issues": "write",
|
||
"members": "read",
|
||
"metadata": "read",
|
||
"pull_requests": "write",
|
||
"statuses": "write"
|
||
},
|
||
"events": [
|
||
"issues",
|
||
"issue_comment",
|
||
"label",
|
||
"organization",
|
||
"pull_request",
|
||
"pull_request_review",
|
||
"pull_request_review_comment",
|
||
"pull_request_review_thread",
|
||
"release",
|
||
"repository"
|
||
]
|
||
}
|
||
},
|
||
{
|
||
"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4253789701",
|
||
"html_url": "https://github.com/laurent22/joplin/pull/15113#issuecomment-4253789701",
|
||
"issue_url": "https://api.github.com/repos/laurent22/joplin/issues/15113",
|
||
"id": 4253789701,
|
||
"node_id": "IC_kwDOBLftOs79i64F",
|
||
"user": {
|
||
"login": "bhaktideshmukh",
|
||
"id": 78796264,
|
||
"node_id": "MDQ6VXNlcjc4Nzk2MjY0",
|
||
"avatar_url": "https://avatars.githubusercontent.com/u/78796264?v=4",
|
||
"gravatar_id": "",
|
||
"url": "https://api.github.com/users/bhaktideshmukh",
|
||
"html_url": "https://github.com/bhaktideshmukh",
|
||
"followers_url": "https://api.github.com/users/bhaktideshmukh/followers",
|
||
"following_url": "https://api.github.com/users/bhaktideshmukh/following{/other_user}",
|
||
"gists_url": "https://api.github.com/users/bhaktideshmukh/gists{/gist_id}",
|
||
"starred_url": "https://api.github.com/users/bhaktideshmukh/starred{/owner}{/repo}",
|
||
"subscriptions_url": "https://api.github.com/users/bhaktideshmukh/subscriptions",
|
||
"organizations_url": "https://api.github.com/users/bhaktideshmukh/orgs",
|
||
"repos_url": "https://api.github.com/users/bhaktideshmukh/repos",
|
||
"events_url": "https://api.github.com/users/bhaktideshmukh/events{/privacy}",
|
||
"received_events_url": "https://api.github.com/users/bhaktideshmukh/received_events",
|
||
"type": "User",
|
||
"user_view_type": "public",
|
||
"site_admin": false
|
||
},
|
||
"created_at": "2026-04-15T16:35:24Z",
|
||
"updated_at": "2026-04-15T16:35:24Z",
|
||
"body": "I have read the CLA Document and I hereby sign the CLA",
|
||
"author_association": "NONE",
|
||
"reactions": {
|
||
"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4253789701/reactions",
|
||
"total_count": 0,
|
||
"+1": 0,
|
||
"-1": 0,
|
||
"laugh": 0,
|
||
"hooray": 0,
|
||
"confused": 0,
|
||
"heart": 0,
|
||
"rocket": 0,
|
||
"eyes": 0
|
||
},
|
||
"performed_via_github_app": null
|
||
},
|
||
{
|
||
"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4257459120",
|
||
"html_url": "https://github.com/laurent22/joplin/pull/15113#issuecomment-4257459120",
|
||
"issue_url": "https://api.github.com/repos/laurent22/joplin/issues/15113",
|
||
"id": 4257459120,
|
||
"node_id": "IC_kwDOBLftOs79w6uw",
|
||
"user": {
|
||
"login": "bhaktideshmukh",
|
||
"id": 78796264,
|
||
"node_id": "MDQ6VXNlcjc4Nzk2MjY0",
|
||
"avatar_url": "https://avatars.githubusercontent.com/u/78796264?v=4",
|
||
"gravatar_id": "",
|
||
"url": "https://api.github.com/users/bhaktideshmukh",
|
||
"html_url": "https://github.com/bhaktideshmukh",
|
||
"followers_url": "https://api.github.com/users/bhaktideshmukh/followers",
|
||
"following_url": "https://api.github.com/users/bhaktideshmukh/following{/other_user}",
|
||
"gists_url": "https://api.github.com/users/bhaktideshmukh/gists{/gist_id}",
|
||
"starred_url": "https://api.github.com/users/bhaktideshmukh/starred{/owner}{/repo}",
|
||
"subscriptions_url": "https://api.github.com/users/bhaktideshmukh/subscriptions",
|
||
"organizations_url": "https://api.github.com/users/bhaktideshmukh/orgs",
|
||
"repos_url": "https://api.github.com/users/bhaktideshmukh/repos",
|
||
"events_url": "https://api.github.com/users/bhaktideshmukh/events{/privacy}",
|
||
"received_events_url": "https://api.github.com/users/bhaktideshmukh/received_events",
|
||
"type": "User",
|
||
"user_view_type": "public",
|
||
"site_admin": false
|
||
},
|
||
"created_at": "2026-04-16T04:50:31Z",
|
||
"updated_at": "2026-04-16T04:50:31Z",
|
||
"body": "@laurent22 Please review this PR, let me know if any changes are required. If not, please approve, so I'll merge this PR, thanks.\r\nCC @f3tony",
|
||
"author_association": "NONE",
|
||
"reactions": {
|
||
"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4257459120/reactions",
|
||
"total_count": 0,
|
||
"+1": 0,
|
||
"-1": 0,
|
||
"laugh": 0,
|
||
"hooray": 0,
|
||
"confused": 0,
|
||
"heart": 0,
|
||
"rocket": 0,
|
||
"eyes": 0
|
||
},
|
||
"performed_via_github_app": null
|
||
},
|
||
{
|
||
"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4273582409",
|
||
"html_url": "https://github.com/laurent22/joplin/pull/15113#issuecomment-4273582409",
|
||
"issue_url": "https://api.github.com/repos/laurent22/joplin/issues/15113",
|
||
"id": 4273582409,
|
||
"node_id": "IC_kwDOBLftOs7-ubFJ",
|
||
"user": {
|
||
"login": "bhaktideshmukh",
|
||
"id": 78796264,
|
||
"node_id": "MDQ6VXNlcjc4Nzk2MjY0",
|
||
"avatar_url": "https://avatars.githubusercontent.com/u/78796264?v=4",
|
||
"gravatar_id": "",
|
||
"url": "https://api.github.com/users/bhaktideshmukh",
|
||
"html_url": "https://github.com/bhaktideshmukh",
|
||
"followers_url": "https://api.github.com/users/bhaktideshmukh/followers",
|
||
"following_url": "https://api.github.com/users/bhaktideshmukh/following{/other_user}",
|
||
"gists_url": "https://api.github.com/users/bhaktideshmukh/gists{/gist_id}",
|
||
"starred_url": "https://api.github.com/users/bhaktideshmukh/starred{/owner}{/repo}",
|
||
"subscriptions_url": "https://api.github.com/users/bhaktideshmukh/subscriptions",
|
||
"organizations_url": "https://api.github.com/users/bhaktideshmukh/orgs",
|
||
"repos_url": "https://api.github.com/users/bhaktideshmukh/repos",
|
||
"events_url": "https://api.github.com/users/bhaktideshmukh/events{/privacy}",
|
||
"received_events_url": "https://api.github.com/users/bhaktideshmukh/received_events",
|
||
"type": "User",
|
||
"user_view_type": "public",
|
||
"site_admin": false
|
||
},
|
||
"created_at": "2026-04-18T11:54:31Z",
|
||
"updated_at": "2026-04-18T11:54:31Z",
|
||
"body": "@laurent22 Whom should I reach out to review this PR?",
|
||
"author_association": "NONE",
|
||
"reactions": {
|
||
"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4273582409/reactions",
|
||
"total_count": 0,
|
||
"+1": 0,
|
||
"-1": 0,
|
||
"laugh": 0,
|
||
"hooray": 0,
|
||
"confused": 0,
|
||
"heart": 0,
|
||
"rocket": 0,
|
||
"eyes": 0
|
||
},
|
||
"performed_via_github_app": null
|
||
},
|
||
{
|
||
"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4273959314",
|
||
"html_url": "https://github.com/laurent22/joplin/pull/15113#issuecomment-4273959314",
|
||
"issue_url": "https://api.github.com/repos/laurent22/joplin/issues/15113",
|
||
"id": 4273959314,
|
||
"node_id": "IC_kwDOBLftOs7-v3GS",
|
||
"user": {
|
||
"login": "mrjo118",
|
||
"id": 6963004,
|
||
"node_id": "MDQ6VXNlcjY5NjMwMDQ=",
|
||
"avatar_url": "https://avatars.githubusercontent.com/u/6963004?v=4",
|
||
"gravatar_id": "",
|
||
"url": "https://api.github.com/users/mrjo118",
|
||
"html_url": "https://github.com/mrjo118",
|
||
"followers_url": "https://api.github.com/users/mrjo118/followers",
|
||
"following_url": "https://api.github.com/users/mrjo118/following{/other_user}",
|
||
"gists_url": "https://api.github.com/users/mrjo118/gists{/gist_id}",
|
||
"starred_url": "https://api.github.com/users/mrjo118/starred{/owner}{/repo}",
|
||
"subscriptions_url": "https://api.github.com/users/mrjo118/subscriptions",
|
||
"organizations_url": "https://api.github.com/users/mrjo118/orgs",
|
||
"repos_url": "https://api.github.com/users/mrjo118/repos",
|
||
"events_url": "https://api.github.com/users/mrjo118/events{/privacy}",
|
||
"received_events_url": "https://api.github.com/users/mrjo118/received_events",
|
||
"type": "User",
|
||
"user_view_type": "public",
|
||
"site_admin": false
|
||
},
|
||
"created_at": "2026-04-18T15:03:43Z",
|
||
"updated_at": "2026-04-18T15:03:43Z",
|
||
"body": "You just need to wait and be patient",
|
||
"author_association": "COLLABORATOR",
|
||
"reactions": {
|
||
"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4273959314/reactions",
|
||
"total_count": 1,
|
||
"+1": 1,
|
||
"-1": 0,
|
||
"laugh": 0,
|
||
"hooray": 0,
|
||
"confused": 0,
|
||
"heart": 0,
|
||
"rocket": 0,
|
||
"eyes": 0
|
||
},
|
||
"performed_via_github_app": null
|
||
},
|
||
{
|
||
"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4275678826",
|
||
"html_url": "https://github.com/laurent22/joplin/pull/15113#issuecomment-4275678826",
|
||
"issue_url": "https://api.github.com/repos/laurent22/joplin/issues/15113",
|
||
"id": 4275678826,
|
||
"node_id": "IC_kwDOBLftOs7-2a5q",
|
||
"user": {
|
||
"login": "laurent22",
|
||
"id": 1285584,
|
||
"node_id": "MDQ6VXNlcjEyODU1ODQ=",
|
||
"avatar_url": "https://avatars.githubusercontent.com/u/1285584?v=4",
|
||
"gravatar_id": "",
|
||
"url": "https://api.github.com/users/laurent22",
|
||
"html_url": "https://github.com/laurent22",
|
||
"followers_url": "https://api.github.com/users/laurent22/followers",
|
||
"following_url": "https://api.github.com/users/laurent22/following{/other_user}",
|
||
"gists_url": "https://api.github.com/users/laurent22/gists{/gist_id}",
|
||
"starred_url": "https://api.github.com/users/laurent22/starred{/owner}{/repo}",
|
||
"subscriptions_url": "https://api.github.com/users/laurent22/subscriptions",
|
||
"organizations_url": "https://api.github.com/users/laurent22/orgs",
|
||
"repos_url": "https://api.github.com/users/laurent22/repos",
|
||
"events_url": "https://api.github.com/users/laurent22/events{/privacy}",
|
||
"received_events_url": "https://api.github.com/users/laurent22/received_events",
|
||
"type": "User",
|
||
"user_view_type": "public",
|
||
"site_admin": false
|
||
},
|
||
"created_at": "2026-04-19T10:07:48Z",
|
||
"updated_at": "2026-04-19T10:07:48Z",
|
||
"body": "Please see Claude's review:\r\n\r\n## Critical / Bugs\r\n\r\n### 1\\. Race condition with 50ms `setTimeout` for clipboard read\r\n\r\nIn `TinyMCE.tsx`, both `onCopy` and `onCut` use `setTimeout(() => { clipboard.readHTML(); ... }, 50)` to read the clipboard after the native copy/cut completes. The 50ms delay is arbitrary — there's no guarantee the native clipboard write finishes in time. On slow machines, `clipboard.readHTML()` could return stale content.\r\n\r\n### 2\\. Pasting into tables bypasses HTML sanitization\r\n\r\nWhen `inTable` is true, `processPastedHtml` is called with `null` for both `htmlToMarkdown` and `markupToHtml` converters, skipping the Markdown round-trip sanitization. This could allow unsanitized HTML to be inserted when pasting into a table cell. TinyMCE's own content filtering should still apply, but this weakens the defense-in-depth.\r\n\r\n### 3. `ContextMenuOptions` interface likely not updated\r\n\r\n`fireEditorEvent` was changed to accept `TinyMceEditorEvents|string` in the implementation (`useContextMenu.ts`), but the interface definition in `contextMenuUtils.ts` (not in the PR) likely still types it as `TinyMceEditorEvents`. This could cause a type error or silently allow any string.\r\n\r\n* * *\r\n\r\n## Medium — Design / Type Safety / Duplication\r\n\r\n### 4\\. Duplicated table cell selection detection (3 times)\r\n\r\nThe same logic to detect multi-cell table selections is repeated **3 times**:\r\n\r\n```typescript\r\nconst selectedCells = editor.dom.select('td[data-mce-selected=\"1\"], th[data-mce-selected=\"1\"]');\r\nif (selectedCells.length > 1 || editor.dom.select('tr[data-mce-selected=\"1\"]').length > 0) {\r\n```\r\n\r\nIt appears in:\r\n\r\n- `TinyMCE.tsx` — `onCopy`\r\n- `TinyMCE.tsx` — `onCut`\r\n- `useContextMenu.ts` — `htmlToCopy`\r\n\r\nAdditionally, `onCopy` and `onCut` share nearly identical bodies — both read the clipboard after a 50ms timeout and call `copyHtmlToClipboard`, with the only difference being `onCut` additionally calls `onChangeHandler()`. This should be extracted to:\r\n\r\n- A `hasTableCellSelection(editor)` helper for the detection\r\n- A shared handler for the copy-to-clipboard-after-timeout logic, parameterized by whether it's a cut\r\n\r\n### 5\\. Magic string `'table-selected'` as sentinel value\r\n\r\nThe literal string `'table-selected'` flows through `htmlToCopy` across 3 files (`useContextMenu.ts`, `contextMenu.ts` x2). It should be extracted to a shared constant. While extremely unlikely, if a user's actual selection were exactly `\"table-selected\"`, it would be misinterpreted.\r\n\r\n### 6\\. Type widening — `fireEditorEvent` accepts any `string`\r\n\r\nThe parameter type was changed from `TinyMceEditorEvents` to `TinyMceEditorEvents|string`, which is too broad. Should be narrowed to `TinyMceEditorEvents | 'execCommandCopy' | 'execCommandCut'`.\r\n\r\n### 7. `document.execCommand('copy'/'cut')` is deprecated\r\n\r\nThe PR introduces `editor.getDoc().execCommand('copy')` and `execCommand('cut')`. These are deprecated DOM APIs. They still work in Electron/Chromium, but worth noting for future maintenance.\r\n\r\n* * *\r\n\r\n## Low — Style Violations\r\n\r\n### 8\\. 12 unrelated whitespace changes in `TinyMCE.tsx`\r\n\r\nThe PR includes formatting-only changes that violate the project guideline \"Do not make white space changes\":\r\n\r\n- Spaces added around `|` in type unions (e.g., `HTMLDivElement|null` → `HTMLDivElement | null`) — 3 instances\r\n- Spaces added inside empty arrow functions (`() => {}` → `() => { }`) — 7 instances\r\n- Tab replaced with space in a `return` statement — 1 instance\r\n- Space added before `/>` in JSX self-closing tag — 1 instance\r\n\r\nThese should all be reverted.\r\n\r\n* * *\r\n\r\n## Summary\r\n\r\nThe approach (delegating table operations to TinyMCE's native handling) is reasonable, but the implementation has some rough edges: the `setTimeout` race condition (**#1**), bypassed sanitization (**#2**), significant code duplication (**#4**), and the magic string sentinel (**#5**) are the main concerns. The whitespace changes (**#8**) should be dropped from the PR.",
|
||
"author_association": "OWNER",
|
||
"reactions": {
|
||
"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4275678826/reactions",
|
||
"total_count": 0,
|
||
"+1": 0,
|
||
"-1": 0,
|
||
"laugh": 0,
|
||
"hooray": 0,
|
||
"confused": 0,
|
||
"heart": 0,
|
||
"rocket": 0,
|
||
"eyes": 0
|
||
},
|
||
"performed_via_github_app": null
|
||
},
|
||
{
|
||
"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4353797017",
|
||
"html_url": "https://github.com/laurent22/joplin/pull/15113#issuecomment-4353797017",
|
||
"issue_url": "https://api.github.com/repos/laurent22/joplin/issues/15113",
|
||
"id": 4353797017,
|
||
"node_id": "IC_kwDOBLftOs8AAAABA4GrmQ",
|
||
"user": {
|
||
"login": "laurent22",
|
||
"id": 1285584,
|
||
"node_id": "MDQ6VXNlcjEyODU1ODQ=",
|
||
"avatar_url": "https://avatars.githubusercontent.com/u/1285584?v=4",
|
||
"gravatar_id": "",
|
||
"url": "https://api.github.com/users/laurent22",
|
||
"html_url": "https://github.com/laurent22",
|
||
"followers_url": "https://api.github.com/users/laurent22/followers",
|
||
"following_url": "https://api.github.com/users/laurent22/following{/other_user}",
|
||
"gists_url": "https://api.github.com/users/laurent22/gists{/gist_id}",
|
||
"starred_url": "https://api.github.com/users/laurent22/starred{/owner}{/repo}",
|
||
"subscriptions_url": "https://api.github.com/users/laurent22/subscriptions",
|
||
"organizations_url": "https://api.github.com/users/laurent22/orgs",
|
||
"repos_url": "https://api.github.com/users/laurent22/repos",
|
||
"events_url": "https://api.github.com/users/laurent22/events{/privacy}",
|
||
"received_events_url": "https://api.github.com/users/laurent22/received_events",
|
||
"type": "User",
|
||
"user_view_type": "public",
|
||
"site_admin": false
|
||
},
|
||
"created_at": "2026-04-30T15:26:51Z",
|
||
"updated_at": "2026-04-30T15:26:51Z",
|
||
"body": "Closing stale PR",
|
||
"author_association": "OWNER",
|
||
"reactions": {
|
||
"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4353797017/reactions",
|
||
"total_count": 0,
|
||
"+1": 0,
|
||
"-1": 0,
|
||
"laugh": 0,
|
||
"hooray": 0,
|
||
"confused": 0,
|
||
"heart": 0,
|
||
"rocket": 0,
|
||
"eyes": 0
|
||
},
|
||
"performed_via_github_app": null
|
||
},
|
||
{
|
||
"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4353931220",
|
||
"html_url": "https://github.com/laurent22/joplin/pull/15113#issuecomment-4353931220",
|
||
"issue_url": "https://api.github.com/repos/laurent22/joplin/issues/15113",
|
||
"id": 4353931220,
|
||
"node_id": "IC_kwDOBLftOs8AAAABA4O31A",
|
||
"user": {
|
||
"login": "f3tony",
|
||
"id": 265374177,
|
||
"node_id": "U_kgDOD9FJ4Q",
|
||
"avatar_url": "https://avatars.githubusercontent.com/u/265374177?v=4",
|
||
"gravatar_id": "",
|
||
"url": "https://api.github.com/users/f3tony",
|
||
"html_url": "https://github.com/f3tony",
|
||
"followers_url": "https://api.github.com/users/f3tony/followers",
|
||
"following_url": "https://api.github.com/users/f3tony/following{/other_user}",
|
||
"gists_url": "https://api.github.com/users/f3tony/gists{/gist_id}",
|
||
"starred_url": "https://api.github.com/users/f3tony/starred{/owner}{/repo}",
|
||
"subscriptions_url": "https://api.github.com/users/f3tony/subscriptions",
|
||
"organizations_url": "https://api.github.com/users/f3tony/orgs",
|
||
"repos_url": "https://api.github.com/users/f3tony/repos",
|
||
"events_url": "https://api.github.com/users/f3tony/events{/privacy}",
|
||
"received_events_url": "https://api.github.com/users/f3tony/received_events",
|
||
"type": "User",
|
||
"user_view_type": "public",
|
||
"site_admin": false
|
||
},
|
||
"created_at": "2026-04-30T15:45:08Z",
|
||
"updated_at": "2026-04-30T15:45:08Z",
|
||
"body": "What about the issue? will this still get resolved? ",
|
||
"author_association": "NONE",
|
||
"reactions": {
|
||
"url": "https://api.github.com/repos/laurent22/joplin/issues/comments/4353931220/reactions",
|
||
"total_count": 0,
|
||
"+1": 0,
|
||
"-1": 0,
|
||
"laugh": 0,
|
||
"hooray": 0,
|
||
"confused": 0,
|
||
"heart": 0,
|
||
"rocket": 0,
|
||
"eyes": 0
|
||
},
|
||
"performed_via_github_app": null
|
||
}
|
||
]
|
||
} |