diff --git a/ROADMAP.md b/ROADMAP.md index 8443ae9e6..054d0f28a 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -388,7 +388,7 @@ list) · [roadmap.md](docs/roadmap.md) (milestones, plan) · [parity-checklist.m Newest first. -- **2026-10-31** · A `.designcraft` file opened from bytes (`file.openBytes` with its file name, as a browser or host passes it) is titled without the extension, as an IDML file opened that way is. Saving it in the browser downloaded `Brochure.designcraft.designcraft`, and the File Name variable showed the doubled name. No readiness percentage change. +- **2026-10-31** · A `.designcraft` file opened from bytes (`file.openBytes` with its file name, as a browser or host passes it) is titled without the extension, as an IDML file opened that way is. Saving it in the browser downloaded `Brochure.designcraft.designcraft`, and the File Name variable showed the doubled name. Browser Open and Drop pass the full file name, so only the engine removes the extension and a repeated suffix is kept in the title. No readiness percentage change. - **2026-10-30** · Import warnings about a story have a Show button: it closes the warnings (the status line keeps them) and selects the story's first frame, fitted in the window. `file.open` returns `warningItems`, the frame each IDML or InDesign warning is about (or null), matching the converter's INDD story numbers (`story 30892`, written to IDML as `u78ac`) and IDML `Self` names to the imported stories. No readiness percentage change. - **2026-10-30** · Parent pages: a running-header variable shows its name in angle brackets on the parent itself (it was blank), as InDesign shows it; on the document pages, and in text with no page, it shows its text as before. No readiness percentage change. - **2026-10-30** · Without facing pages, a page of a multi-page spread shows the parent page in its place, as in InDesign: the second page of a two-page spread shows the parent's second page. Every single-sided page showed the parent's first page, so an InDesign book set up without facing pages but laid out in two-page spreads repeated the left parent page's items (a black heading bar) on its right pages and lost the right parent page's. No readiness percentage change. diff --git a/crates/ui-egui/src/app/files.rs b/crates/ui-egui/src/app/files.rs index b5de53ab1..68155d884 100644 --- a/crates/ui-egui/src/app/files.rs +++ b/crates/ui-egui/src/app/files.rs @@ -161,8 +161,7 @@ impl DesignApp { } else if place { self.open_file("file.place", json!({"name": file.name, "base64": b64})) } else { - let title = file.name.rsplit_once('.').map_or(file.name.as_str(), |(stem, _)| stem); - self.open_file("file.openBytes", json!({"name": title, "base64": b64})) + self.open_file("file.openBytes", json!({"name": file.name, "base64": b64})) } } @@ -377,7 +376,7 @@ mod import_warning_tests { let request = app.import_request("open"); app.services.inbox.as_ref().unwrap().lock().unwrap().push(ImportedFile { request, name: "partial.idml".into(), bytes: idml(true) }); app.drain_inbox(); - assert_partial_import_warning(&mut app, "partial"); + assert_partial_import_warning(&mut app, "partial.idml"); } #[test] @@ -424,6 +423,34 @@ pub(crate) mod browser_import_tests { app.services.inbox.as_ref().unwrap().lock().unwrap().push(ImportedFile { request, name: name.into(), bytes }); app.drain_inbox(); } + + /// A document chosen or dropped in the browser is titled by its file name less one extension, + /// as on the desktop: the extension comes off once, in the engine. + #[test] + fn browser_opens_title_a_document_by_its_name_without_one_extension() { + let mut app = app(); + let native = designcraft_engine::cmd::base64_decode(app.run("file.serialize", json!({})).unwrap()["base64"].as_str().unwrap()); + for purpose in ["open", "drop"] { + for (name, title) in [ + ("Brochure.designcraft", "Brochure"), + ("Brochure.designcraft.designcraft", "Brochure.designcraft"), + ("Brochure.v2.designcraft", "Brochure.v2"), + ("日本.DESIGNCRAFT", "日本"), + (".designcraft", ".designcraft"), + ("Brochure", "Brochure"), + ] { + let request = app.import_request(purpose); + deliver(&mut app, request, name, native.clone()); + assert_eq!(app.session.doc().unwrap().doc.title, title, "{purpose}: {name}"); + } + } + let idml = designcraft_idml::export_idml(&app.session.doc().unwrap().doc); + for purpose in ["open", "drop"] { + let request = app.import_request(purpose); + deliver(&mut app, request, "Brochure.idml", idml.clone()); + assert_eq!(app.session.doc().unwrap().doc.title, "Brochure", "{purpose}: IDML"); + } + } fn image() -> Vec { br##""##.to_vec() }