mirror of
https://github.com/storytold/wordcraft.git
synced 2026-11-09 11:50:20 -06:00
#1537: review — a browser's Mod+Shift+V paste event pastes text only, once (CodeRabbit)
On the web the key no longer pastes as well: the paste event that follows carries the text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
30ee8bb450
commit
43d9542c3d
@@ -510,9 +510,12 @@ fn handle_event(app: &mut WordApp, ctx: &egui::Context, e: egui::Event) {
|
||||
egui::Event::Paste(t) => {
|
||||
// Mod+Alt+V arrives as a paste too (the shell reads the clipboard): Paste Special.
|
||||
let m = ctx.input(|i| i.modifiers);
|
||||
// A browser sends Mod+Shift+V as a paste too: Keep Text Only, as the key does on the
|
||||
// desktop (#1537). (egui-winit sends that chord as a key, and Shift+Insert has no Mod.)
|
||||
let id = match (m.alt, m.shift) {
|
||||
(true, true) => "edit.pasteText",
|
||||
(true, false) => "edit.pasteSpecial",
|
||||
(false, true) if m.command => "edit.pasteText",
|
||||
_ => "edit.paste",
|
||||
};
|
||||
let _ = app.run(id, json!({"text": t}));
|
||||
|
||||
@@ -134,7 +134,15 @@ pub(super) fn dispatch(app: &mut WordApp, key: Key, m: Modifiers) -> bool {
|
||||
}
|
||||
// Mod+Shift+V pastes the formatting Mod+Shift+C picked up; with none picked up it pastes
|
||||
// the clipboard as text only, as Word for Windows does (#1537, #4943).
|
||||
let id = if spec.id == "edit.pasteFormat" && app.session.painter.is_none() { "edit.pasteText" } else { spec.id };
|
||||
let id = if spec.id == "edit.pasteFormat" && app.session.painter.is_none() {
|
||||
// On the web the browser's paste event that follows carries the text: paste once, there.
|
||||
if cfg!(target_arch = "wasm32") {
|
||||
return true;
|
||||
}
|
||||
"edit.pasteText"
|
||||
} else {
|
||||
spec.id
|
||||
};
|
||||
let _ = app.run(id, json!({}));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -133,6 +133,21 @@ fn only_plain_paste_releases_paste_a_clipboard_picture() {
|
||||
assert!(!is_paste_special_release(Key::V, m(true, true, true)) && !is_paste_special_release(Key::V, m(true, false, false)));
|
||||
}
|
||||
|
||||
/// #1537: a browser sends Mod+Shift+V as a paste event; it pastes text only, in the destination's
|
||||
/// formatting, though the clipboard also holds bold HTML. Plain Mod+V keeps the HTML's bold.
|
||||
#[test]
|
||||
fn a_mod_shift_paste_event_keeps_text_only() {
|
||||
for (modifiers, bold) in [(Modifiers::COMMAND | Modifiers::SHIFT, false), (Modifiers::COMMAND, true)] {
|
||||
let services = crate::Services { clipboard_html: Some(Box::new(|| Some("<p><b>external</b></p>".into()))), ..Default::default() };
|
||||
let mut a = WordApp::new(wordcraft_engine::Session::new(wordcraft_doc::Document::new()), services);
|
||||
let ctx = egui::Context::default();
|
||||
mods_frame(&ctx, &mut a, modifiers, vec![egui::Event::Paste("external".into())]);
|
||||
assert_eq!(a.session.doc.plain_text(wordcraft_doc::StoryRef::Body), "external", "{modifiers:?}");
|
||||
let state = a.session.run("format.state", &json!({})).unwrap();
|
||||
assert_eq!(state.get("bold").and_then(serde_json::Value::as_bool) == Some(true), bold, "{modifiers:?}: {state}");
|
||||
}
|
||||
}
|
||||
|
||||
/// An empty document whose clipboard holds a 4 × 4 picture.
|
||||
fn picture_app() -> WordApp {
|
||||
use crate::paste_picture::ClipboardPicture;
|
||||
|
||||
Reference in New Issue
Block a user