[Beta]: On Android Chrome, paste inserts the copied text twice, and later typing lands between the copies or elsewhere
Maintainer thường phản hồi trong vòng 1 ngày
@natamox đang làm issue này rồi.
Từ ngày 27/10/2026.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 45/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- react, typescript
- Lĩnh vực
- backend-api-design, frontend
Hướng nghiên cứu
Start by reading packages/plitejs/src/react/editable/clipboard-input-strategy.ts around applyEditablePaste and packages/plitejs/src/react/hooks/android-input-manager/android-input-manager.ts around the insertFromPaste branch. Compare how the paste and beforeinput events are handled on Android, then check the existing tests for these paths. Done means Android Chrome inserts copied text once, leaves the caret after it, and subsequent taps place the caret correctly.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Testing lane
- Repository:
udecode/plate - Branch:
next - Release channel: Beta
- Exact commit/package version:
NOT_ENOUGH_INFO
Summary
On Android Chrome, Paste from the long-press menu inserts the copied text twice on Beta. The caret then sits between the two copies, so the next typed letter goes there. After a tap outside the editor and a tap back at the end of the text, the caret can also land somewhere else in the paragraph. Nine Beta examples show it. Five of them have a Slate counterpart, and on slatejs.org the same steps paste the text once in all five.
Reproduction
Repro 1: /examples/plite/plaintext, Android Chrome
- Open https://beta.platejs.org/examples/plite/plaintext.
- Tap the end of the text and type
alpha beta. The recorded run then pressed Delete, pressed Enter, typedgamma, pressed Delete six times to removegammaand the line break, and committed你好with pinyinnihao. The text now endsalpha bet你好. - Long-press
alphaand tap 复制 (Copy). - Tap the end of the text.
- Long-press the end of the text and tap 粘贴 (Paste).
- Tap outside the editor. In the recorded run the tap lands on the page heading.
- Tap the end of the text again and type
z.
After step 5 the text ends alpha bet你好alphaalpha, with the caret between the two copies. In step 7 the caret lands after This at the start of the paragraph, and z goes there: This zis editable plain text. On https://www.slatejs.org/examples/plaintext the same steps paste alpha once, and z lands at the end: alpha bet你好alphaz.
Repro 2: /examples/plite/comment-mode, Android Chrome
The Edit mode panel is the editor whose header reads Edit mode and document writes enabled.
- Open https://beta.platejs.org/examples/plite/comment-mode.
- In the
Edit modepanel, long-pressanchoredin the first paragraph and tap 复制 (Copy). - Tap the end of the second paragraph, after
sync.. - Long-press the same spot and tap 粘贴 (Paste).
- Type
z. - Tap outside the editor, then tap
Clear comments.
After step 4 the second paragraph ends sync.anchoredanchored, with the caret between the copies. z lands there: sync.anchoredzanchored. The comment's range does not move. After step 6 the paragraph ends sync.anchoredz, and the copy after z is gone. In the recording it is already gone when the page has scrolled down to the buttons and the comment card is still on screen, before Clear comments removes the comment.
The recorded run did nine other steps on the page first. It seeded, retoned and updated a comment, and typed and deleted 你好 and a line break in Edit mode. slatejs.org has no matching example.
Other examples, Android Chrome
The same paste went in twice on seven more examples, in runs on the same phone on the same day. Each copied a word with a long press and Copy, tapped the end of the text, long-pressed it and tapped Paste. Where the table says so, the run then tapped outside the editor and back at the end before typing z.
| Example | Copied | Text after the paste | Where z landed |
slatejs.org |
|---|---|---|---|---|
| /examples/plite/editable-voids, outer editor | addition |
first paragraph ends 你好additionaddition |
between the copies: additionzaddition |
pasted once, z after it |
| /examples/plite/huge-document | a word such as aliquam |
first paragraph ends aliquamaliquam |
after a tap at the end of the first paragraph, between Suppel and lex |
pasted once |
| /examples/plite/markdown-preview | alpha |
text ends 你好alphaalpha |
after a tap outside and back at the end, inside it: Try izt out. The **bold** typed next went there too |
pasted once, z at the end |
| /examples/plite/shadow-dom | alpha |
text ends 你好alphaalpha |
after a tap outside and back at the end, between the copies: alphazalpha |
pasted once, z at the end |
| /examples/plite/document-state, body editor | body |
second paragraph ends nodes.bodybody |
between the copies: bodyzbody. Undo document change removed the z |
no matching example |
| /examples/plite/inline-void-drag | two |
text ends three你好twotwo |
between the copies: twoztwo |
no matching example |
| /examples/plite/schema-reconfiguration, named root | beforeguardafter. A long press on after in the primary root selects the whole run |
named root reads beforeguardafter three times |
not typed | no matching example |
On /examples/plite/schema-reconfiguration, a tap inside the primary root's guard before the long press makes Paste crash the page instead. That is #5243. Without the tap, the paste only goes in twice.
Expected
Paste inserts the copied text once and leaves the caret after it, as on slatejs.org. A later tap at the end of the text puts the caret at the end.
Actual
Paste inserts two copies, and the caret sits between them, so the next letter goes there. After a tap outside and back, the caret can land elsewhere in the paragraph, such as after This in repro 1.
Environment
- Exact
nextcommit/Beta package version:NOT_ENOUGH_INFO - Device: Xiaomi 14, Android 16, Chrome 154, WeType pinyin keyboard in its 9-key layout. An agent ran every repro and every example in the table on natamox's real phone on 2026-10-23 (PT), with slatejs.org as the reference where Slate has the same example. These are agent runs, not tests by hand, and nobody has retested them by hand.
- Nobody has tried these steps on iPhone or iOS Safari.
- An agent's desktop Chrome run on /examples/plite/plaintext on 2026-10-21 copied and pasted
twoonce.
Caveat
- From a reading of the code on
next, which traces the path and does not prove the cause:applyEditablePastehandles thepasteevent (packages/plitejs/src/react/editable/clipboard-input-strategy.ts:980). When the browser supportsbeforeinputand the clipboard holds more than plain text, it leaves the paste tobeforeinput(the condition at:1046). On Android,insertFromPastereachespackages/plitejs/src/react/hooks/android-input-manager/android-input-manager.ts:995. That branch schedules aninsert-datacommand and returns without cancelling the event. - An inference from that reading, not checked with a change: Chrome also inserts the text into the page, so the page shows two copies while the document holds one. A tap is then mapped to a document position through text the document does not have, which would put the caret in the wrong place. An agent's event log on /examples/plite/huge-document recorded a
pasteevent and then abeforeinputwithinsertFromPastefor the same paste. - Repro 2 fits that inference. The copy after
zwent away after the editor lost focus, which suggests it was only on the page and never in the document. Nobody checked the document data. The recording does not show whether the copy went when the page scrolled or when Clear comments was tapped. - Every recorded run typed in the editor before it copied, and each copy came from the same page. Pasting text copied from another app was not tested.
- In the repro 1 recording, the tap in step 4 shows a caret without a drag handle on Beta, while Slate shows one. That is #5247 and not part of this issue.
Evidence
- Repro 1: screen recording from the phone, 26 seconds, cut from a longer run, with an English step panel beside it. The keyboard's suggestion row is blurred, and a note covers the panel's first eight steps. At 0:00 the long press selects
alpha. From 0:12 the long press at the end of the text shows the paste menu. At 0:17 Paste puts inalphaalpha, with the caret between the two copies. At 0:18 the tap outside the editor lands on the page heading, and Chrome's search sheet forPlainopens at the bottom. At 0:20 the tap at the end of the text puts the caret afterThis, and at 0:21zappears there. - Repro 1 reference: slatejs.org with the same steps, 25 seconds, in the same layout. At 0:17 Paste puts in one
alpha. At 0:21zlands at the end, afteralpha. - Repro 2: screen recording from the phone, 28 seconds, cut from a longer run, in the same layout. The top of the screen and the keyboard's suggestion row are blurred, and a note covers the panel's first nine steps. At 0:01 the long press selects
anchored. At 0:17 Paste puts inanchoredanchoredaftersync., with the caret between the copies, and at 0:19zlands there. At 0:21 the tap outside lands on theEdit modeheader and the keyboard closes. The paragraph still endssync.anchoredzanchored. At 0:22 the page jumps down to the buttons, and the paragraph endssync.anchoredzwhile theComment 1 - opencard is still shown. At 0:23 Clear comments removes the comment.
Repro 1 — Android Chrome, /examples/plite/plaintext
https://github.com/user-attachments/assets/8be14122-23fd-4f95-9a43-3432d88db664
Repro 1 reference — Android Chrome, slatejs.org/examples/plaintext
https://github.com/user-attachments/assets/a613f87f-f626-449b-8adc-d2c87a2117ee
Repro 2 — Android Chrome, /examples/plite/comment-mode
https://github.com/user-attachments/assets/ad19fc42-c404-41fb-9ba5-856e9f01c7de
- Ngôn ngữ chính
- TypeScript
- Star
- 16.6k
- Fork
- 993
- Merge trung bình
- 20 giờ 21 phút
- Pull request đã merge (30 ngày)
- 60
Chuẩn bị môi trường
Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của udecode/plate
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
Maintainer thường phản hồi trong vòng 1 ngày
-
[Beta]: After Enter saves an edited link URL, the link toolbar stays hidden while the caret is in the linkCó thể đã có người làm @zbeyens đã nhận 2 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
udecode/plate#5314 · 1 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
[Beta]: The docs Demo example page starts with an empty editorCó thể đã có người làm @natamox đã nhận 3 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
udecode/plate#5308 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của udecode/plate
Issue tương tự
-
b:minor bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
software-mansion/argent#1698 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
e2e-failure ready-to-code
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
redhat-developer/rhdh-plugin-export-overlays#4624 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
better-auth/better-auth#12132 · 1 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày
-
automation missing-model model-sync provider:tinfoil
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
anomalyco/models.dev#12053 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
o8 next debug build aborts on Glass to Dark appearance switch (nil identifier messaged before check)Đang mởbug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
hurttlocker/o8#5112 ·