From 0467e1101b608fd73fe47f0e8e6f46abeb660203 Mon Sep 17 00:00:00 2001 From: Nigel Ihza Firdausy <106657905+Ni-zav@users.noreply.github.com> Date: Sun, 11 Oct 2026 21:46:02 +0700 Subject: [PATCH] fix(script): expose After Effects text Path Options matchNames (#815) --- crates/script/src/matchnames.rs | 12 ++++++++++++ crates/script/src/tests.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/crates/script/src/matchnames.rs b/crates/script/src/matchnames.rs index a48a36a0..42fcbb5f 100644 --- a/crates/script/src/matchnames.rs +++ b/crates/script/src/matchnames.rs @@ -61,6 +61,17 @@ const TEXT: &[(&str, &str)] = &[ ("animators", "ADBE Text Animators"), ]; +// Match names of the six properties below Text ▸ Path Options, as named by +// After Effects' scripting API (rather than EffectCraft's internal ids). +const TEXT_PATH_OPTIONS: &[(&str, &str)] = &[ + ("path", "ADBE Text Path"), + ("reversePath", "ADBE Text Reverse Path"), + ("perpendicular", "ADBE Text Perpendicular To Path"), + ("forceAlignment", "ADBE Text Force Align Path"), + ("firstMargin", "ADBE Text First Margin"), + ("lastMargin", "ADBE Text Last Margin"), +]; + const TEXT_ANIMATOR: &[(&str, &str)] = &[("selectors", "ADBE Text Selectors"), ("properties", "ADBE Text Animator Properties")]; const CAMERA: &[(&str, &str)] = &[ @@ -411,6 +422,7 @@ pub fn node(chain: &[&Node]) -> String { } } "text" if chain.len() == 2 => find(TEXT, id).map(str::to_string).unwrap_or_else(own), + "text" if pid == "pathOptions" => find(TEXT_PATH_OPTIONS, id).map(str::to_string).unwrap_or_else(own), "text" if pid == "animators" => "ADBE Text Animator".into(), "text" if grand.map(|g| g.match_id()) == Some("animators") => find(TEXT_ANIMATOR, id).map(str::to_string).unwrap_or_else(own), "cameraOptions" => find(CAMERA, id).map(str::to_string).unwrap_or_else(own), diff --git a/crates/script/src/tests.rs b/crates/script/src/tests.rs index b50a7bfb..46a2cd52 100644 --- a/crates/script/src/tests.rs +++ b/crates/script/src/tests.rs @@ -730,3 +730,30 @@ fn import_options_sequence_picks_one_still_or_the_run() { assert_eq!(kind_of(&s, "shot_[0001-0003].png"), FootageKind::Sequence); let _ = std::fs::remove_dir_all(&dir); } + +#[test] +fn script_text_path_options_expose_after_effects_match_names() { + let mut s = session(); + let r = ok( + &mut s, + r#" + var c = app.project.items.addComp("Text Path", 160, 90, 1, 2, 24); + var t = c.layers.addText("On a path"); + var options = t.property("ADBE Text Properties").property("ADBE Text Path Options"); + var names = []; + for (var i = 1; i <= options.numProperties; i++) + names.push(options.property(i).matchName); + [names, options.property("ADBE Text Path").matchName, + options.property("ADBE Text Perpendicular To Path").matchName] + "#, + ); + assert_eq!( + r.result, + json!([ + ["ADBE Text Path", "ADBE Text Reverse Path", "ADBE Text Perpendicular To Path", + "ADBE Text Force Align Path", "ADBE Text First Margin", "ADBE Text Last Margin"], + "ADBE Text Path", + "ADBE Text Perpendicular To Path" + ]) + ); +}