mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-29 20:47:18 -06:00
#2495: keep Duplicate from opening browser bookmarks
This commit is contained in:
@@ -7,6 +7,20 @@
|
||||
//
|
||||
// Plain functions only: the Rust side owns the logic.
|
||||
|
||||
// ------------------------------------------------------------------ shortcuts
|
||||
|
||||
/// Keep Duplicate on the app canvas instead of also opening the browser's bookmarks.
|
||||
/// eframe still receives the key; other chords and HTML inputs keep their browser behavior.
|
||||
export function installCanvasShortcuts(canvas) {
|
||||
canvas.addEventListener("keydown", (event) => {
|
||||
if (event.target === canvas && (event.ctrlKey || event.metaKey)
|
||||
&& !event.shiftKey && !event.altKey && !event.isComposing
|
||||
&& event.key.toLowerCase() === "d") {
|
||||
event.preventDefault();
|
||||
}
|
||||
}, { capture: true });
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------ storage
|
||||
|
||||
const DIR = "effectcraft";
|
||||
|
||||
@@ -15,6 +15,8 @@ use wasm_bindgen::prelude::*;
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_name = showDeviceLost)]
|
||||
fn show_device_lost(message: &str, kept: bool);
|
||||
#[wasm_bindgen(js_name = installCanvasShortcuts)]
|
||||
fn install_canvas_shortcuts(canvas: &web_sys::HtmlCanvasElement);
|
||||
}
|
||||
|
||||
/// Work for the UI thread with access to the app (posted by async tasks: picked files…).
|
||||
@@ -204,6 +206,7 @@ pub async fn start(canvas_id: String) -> Result<(), JsValue> {
|
||||
effectcraft_ui_egui::i18n::set_system_locales(query_value("lang"), browser.collect());
|
||||
let doc = web_sys::window().and_then(|w| w.document()).ok_or("no document")?;
|
||||
let canvas: web_sys::HtmlCanvasElement = doc.get_element_by_id(&canvas_id).ok_or("no canvas")?.dyn_into()?;
|
||||
install_canvas_shortcuts(&canvas);
|
||||
let empty = query_flag("empty");
|
||||
let home = query_flag("home");
|
||||
// Browser storage: settings, recent projects, imported media, saved projects, auto-saves and
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
// - A lost WebGPU device: the page says so over the canvas and offers Save Project and Reload;
|
||||
// the reload writes pending changes to browser storage first, and a failed write is reported
|
||||
// instead of reloading (#225).
|
||||
// - Duplicate cancels the browser's bookmark action on the app canvas, while still delivering
|
||||
// the key to the app; other chords and HTML inputs keep their browser behavior (#2495).
|
||||
// Exits non-zero on failure.
|
||||
import assert from "node:assert/strict";
|
||||
import { dirname, join } from "node:path";
|
||||
@@ -58,6 +60,26 @@ globalThis.location = { reload: () => reloads++ };
|
||||
|
||||
const host = await import(pathToFileURL(join(here, "../js/host.js")));
|
||||
|
||||
// #2495: prevent the browser default without swallowing the app's Duplicate key.
|
||||
const canvas = new EventTarget();
|
||||
const input = new EventTarget();
|
||||
host.installCanvasShortcuts(canvas);
|
||||
let delivered = 0;
|
||||
canvas.addEventListener("keydown", () => delivered++);
|
||||
const key = (target, properties) => {
|
||||
const event = new Event("keydown", { cancelable: true });
|
||||
Object.assign(event, { key: "d", ...properties });
|
||||
target.dispatchEvent(event);
|
||||
return event.defaultPrevented;
|
||||
};
|
||||
assert.equal(key(canvas, { ctrlKey: true }), true);
|
||||
assert.equal(key(canvas, { metaKey: true, key: "D" }), true);
|
||||
for (const properties of [{}, { ctrlKey: true, shiftKey: true }, { ctrlKey: true, altKey: true }, { ctrlKey: true, isComposing: true }, { ctrlKey: true, key: "r" }]) {
|
||||
assert.equal(key(canvas, properties), false);
|
||||
}
|
||||
assert.equal(delivered, 7, "all keys still reach the app");
|
||||
assert.equal(key(input, { ctrlKey: true }), false, "an external HTML input keeps its shortcut");
|
||||
|
||||
// #226: one readable and one unreadable file.
|
||||
const file = (name, read) => ({ name, webkitRelativePath: "", arrayBuffer: read });
|
||||
const picked = host.browsePickFiles(false);
|
||||
|
||||
Reference in New Issue
Block a user