Integration: stack #5598 (its merge onto main, conflicts resolved)

This commit is contained in:
David Mann
2026-10-22 23:40:09 +02:00
4 changed files with 41 additions and 3 deletions
-1
View File
@@ -1127,7 +1127,6 @@ pub const HIDDEN_UNTIL_IMPLEMENTED: &[&str] = &[
"unitsAndRulers.gutter",
"plugIns.showExtensionPanels",
"plugIns.allowScriptsToConnect",
"plugIns.generatorEnabled",
"type.textEngine",
"enhancedControls.scrubbySliderAcceleration",
"rawDefaults.colorSpace",
+12 -2
View File
@@ -1515,7 +1515,7 @@ fn image_assets(s: &mut Session, p: &Value) -> Result<Value> {
/// After a save: regenerate the document's image assets when Generate › Image Assets is on.
pub fn on_saved(s: &Session, index: usize) -> Option<Value> {
let d = s.documents().get(index)?;
if !s.file_menu.image_assets.contains(&d.doc.id) || cfg!(target_arch = "wasm32") {
if !s.file_menu.image_assets.contains(&d.doc.id) || !s.prefs().plug_ins.generator_enabled || cfg!(target_arch = "wasm32") {
return None;
}
let dir = assets_dir(d.path.as_deref()?);
@@ -1532,6 +1532,16 @@ pub fn specs() -> Vec<CommandSpec> {
fn has_doc(s: &Session) -> std::result::Result<(), String> {
s.active().map(|_| ()).ok_or_else(|| "no document open".into())
}
/// Generate ▸ Image Assets needs Preferences ▸ Plug-ins ▸ Generator enabled, as in
/// Photoshop (where "Enable Generator" is unchecked until turned on).
fn generator_enabled(s: &Session) -> std::result::Result<(), String> {
has_doc(s)?;
if !s.prefs().plug_ins.generator_enabled {
return Err("Enable Generator in Preferences ▸ Plug-ins".into());
}
Ok(())
}
vec![
spec!(
"file.export.saveForWebLegacy",
@@ -1566,7 +1576,7 @@ pub fn specs() -> Vec<CommandSpec> {
&["File", "Generate"],
None,
r##"{"on":bool? (default: toggle),"dir":folder? (default <document>-assets next to the file)} → {enabled, files, errors}; layers named like "foo.png", "200% foo@2x.png", "48x48 icons/a.png8", "photo.jpg80%" are exported, now and after each save"##,
has_doc,
generator_enabled,
image_assets
),
]
+25
View File
@@ -610,10 +610,35 @@ fn generator_naming_grammar() {
assert!(parse_defaults("defaults are nice", 72.0).is_none());
}
#[test]
fn image_assets_needs_the_generator_preference() {
let dir = tmp("generator_pref");
let mut s = session(8);
let id = s.active().unwrap().active_layer.unwrap();
s.execute("layer.renameLayer", json!({"layer": id.0, "name": "logo.png"})).unwrap();
assert!(!s.prefs().plug_ins.generator_enabled, "off by default, as in Photoshop");
assert!(!s.is_enabled("file.generate.imageAssets"), "unavailable until it is enabled");
assert!(s.execute("file.generate.imageAssets", json!({"dir": dir})).is_err());
s.execute("prefs.set", json!({"path": "plugIns.generatorEnabled", "value": true})).unwrap();
assert!(s.is_enabled("file.generate.imageAssets"));
assert_eq!(s.execute("file.generate.imageAssets", json!({"dir": dir})).unwrap()["enabled"], true);
s.active_mut().unwrap().path = Some(format!("{dir}/doc.psd"));
assert!(crate::automate_cmds::document_saved(&mut s, 0).is_some(), "assets are written on save");
// Turning it off again takes the menu item away and stops the export, even for a document
// left switched on.
s.execute("prefs.set", json!({"path": "plugIns.generatorEnabled", "value": false})).unwrap();
assert!(!s.is_enabled("file.generate.imageAssets"));
assert!(crate::automate_cmds::document_saved(&mut s, 0).is_none(), "no assets while Generator is off");
}
#[test]
fn image_assets_are_generated_now_and_on_save() {
let dir = tmp("assets");
let mut s = session(8);
// Preferences ▸ Plug-ins ▸ Generator enabled: the feature is opt-in.
s.execute("prefs.set", json!({"path": "plugIns.generatorEnabled", "value": true})).unwrap();
let id = s.active().unwrap().active_layer.unwrap();
s.execute("layer.renameLayer", json!({"layer": id.0, "name": "logo.png, 50% small/logo.gif, logo.jpg80%"})).unwrap();
let r = s.execute("file.generate.imageAssets", json!({"dir": dir})).unwrap();
+4
View File
@@ -1822,6 +1822,10 @@ mod tests {
assert_eq!(checked(&app, "view.lockSlices"), Some(false));
crate::menus::invoke(&mut app, &ctx, "view.lockSlices", json!({})).unwrap();
assert_eq!(checked(&app, "view.lockSlices"), Some(true));
// Generator is opt-in (Preferences ▸ Plug-ins), as in Photoshop: the menu item is
// unavailable until it is enabled.
assert!(crate::menus::invoke(&mut app, &ctx, "file.generate.imageAssets", json!({})).is_err());
app.run("prefs.set", json!({"path": "plugIns.generatorEnabled", "value": true})).unwrap();
crate::menus::invoke(&mut app, &ctx, "file.generate.imageAssets", json!({})).unwrap();
assert_eq!(checked(&app, "file.generate.imageAssets"), Some(true));
// Form dialogs open for the rest.