Merge pull request #1172 from redonion23/fix/815-stroke-dash-matchnames

# Conflicts:
#	crates/script/src/tests.rs
This commit is contained in:
Brandon Thomas committed 2026-10-13 04:28:45 -04:00
commit ee682bbfd9
4 files changed
+68

No files matched your search

+19
View File
@@ -72,6 +72,22 @@ const TEXT_PATH_OPTIONS: &[(&str, &str)] = &[
("lastMargin", "ADBE Text Last Margin"),
];
// A stroke's Dashes, as After Effects' scripting API names them (#815).
const STROKE_DASHES: &[(&str, &str)] = &[
("dash", "ADBE Vector Stroke Dash 1"),
("gap", "ADBE Vector Stroke Gap 1"),
("dash2", "ADBE Vector Stroke Dash 2"),
("gap2", "ADBE Vector Stroke Gap 2"),
("dash3", "ADBE Vector Stroke Dash 3"),
("gap3", "ADBE Vector Stroke Gap 3"),
("offset", "ADBE Vector Stroke Offset"),
];
/// The Dashes child id (`dash`, `gap2`, `offset`…) for an After Effects match name.
pub fn stroke_dash(name: &str) -> Option<&'static str> {
STROKE_DASHES.iter().find(|(_, m)| *m == name).map(|(id, _)| *id)
}
const TEXT_ANIMATOR: &[(&str, &str)] = &[("selectors", "ADBE Text Selectors"), ("properties", "ADBE Text Animator Properties")];
const TEXT_SELECTORS: &[(&str, &str)] =
@@ -447,6 +463,9 @@ pub fn node(chain: &[&Node]) -> String {
if let Some((_, _, m)) = SHAPE_PROPS.iter().find(|(item, prop, _)| *item == pid && *prop == id) {
return m.to_string();
}
if pid == "dashes" {
return find(STROKE_DASHES, id).map(str::to_string).unwrap_or_else(own);
}
own()
}
_ => own(),
+9
View File
@@ -661,6 +661,15 @@ fn resolve_add(s: &Session, a: &J) -> R {
}
}
"animators" => json!({"kind": "animator"}),
// A stroke always holds Dash 1, Gap 1 and Offset (Dash 0 draws no dashes); adding one of
// them returns it, Dash/Gap 2 and 3 are added as a pair (`shape.dashes.add`) (#815).
"dashes" if in_group => match matchnames::stroke_dash(name) {
Some(id) => match g.children.iter().find(|n| n.match_id() == id) {
Some(n) => json!({"kind": "existing", "uid": n.uid()}),
None => json!({"kind": "dash", "id": id, "stroke": l.props.parent_of(g.uid).map(|p| p.uid)}),
},
None => json!({"error": format!("Can not add \"{name}\" to Dashes")}),
},
_ if in_contents && in_group => match matchnames::shape_kind(name) {
Some(k) => {
json!({"kind": "shape", "shape": k, "group": if l.props.sub("contents").is_some_and(|c| c.uid == g.uid) { J::Null } else { json!(g.uid) }})
+9
View File
@@ -715,6 +715,15 @@ PropertyGroup.prototype.addProperty = function (name) {
var p = { comp: L.__comp, layer: L.__id, kind: r.shape };
if (r.group !== null && r.group !== undefined) p.group = r.group;
uid = __call("layer.addShapeItem", p).uid;
} else if (r.kind === "existing") {
uid = r.uid;
} else if (r.kind === "dash") {
// Dash/Gap 2 and 3 come as a pair: add pairs until the one asked for exists.
var dp = { comp: L.__comp, layer: L.__id, prop: r.stroke };
for (var n = 0; n < 3 && !this.property(name); n++) __call("shape.dashes.add", dp);
var added = this.property(name);
if (!added) throw __err("Can not add \"" + name + "\" to Dashes");
return added;
} else if (r.kind === "animator") {
uid = __call("layer.addTextAnimator", { comp: L.__comp, layer: L.__id, properties: [] }).animator;
} else if (r.kind === "animatorProperty") {
+31
View File
@@ -928,6 +928,37 @@ fn script_key_lookup_fetches_only_that_key() {
assert_eq!(o.result, json!([2000, 0.08, null, 1998, 0.04, 1998, "keyIndex 1999 is out of range 1..1998"]));
}
/// #815: a stroke's Dashes use After Effects' match names, and addProperty with them returns
/// Dash 1 / Gap 1 / Offset or adds the Dash 2 / Gap 2 pair.
#[test]
fn script_stroke_dashes_use_after_effects_match_names() {
let mut s = session();
let o = ok(
&mut s,
"function names(g) { var a = []; for (var i = 1; i <= g.numProperties; i++) a.push(g.property(i).matchName); return a.join(','); }\
var comp = app.project.items.addComp('Names', 100, 100, 1, 10, 25);\
var contents = comp.layers.addShape().property('ADBE Root Vectors Group'); contents.addProperty('ADBE Vector Shape - Rect');\
var d = contents.addProperty('ADBE Vector Graphic - Stroke').property('ADBE Vector Stroke Dashes');\
var before = names(d);\
var dash1 = d.addProperty('ADBE Vector Stroke Dash 1'); dash1.setValue(12);\
var gap2 = d.addProperty('ADBE Vector Stroke Gap 2');\
var err = ''; try { d.addProperty('ADBE Vector Stroke Dash 9'); } catch (e) { err = e.message; }\
[before, dash1.matchName, d.property('ADBE Vector Stroke Dash 1').value, d.property('ADBE Vector Stroke Offset').matchName, gap2.matchName, names(d), err]",
);
assert_eq!(
o.result,
json!([
"ADBE Vector Stroke Dash 1,ADBE Vector Stroke Gap 1,ADBE Vector Stroke Offset",
"ADBE Vector Stroke Dash 1",
12,
"ADBE Vector Stroke Offset",
"ADBE Vector Stroke Gap 2",
"ADBE Vector Stroke Dash 1,ADBE Vector Stroke Gap 1,ADBE Vector Stroke Dash 2,ADBE Vector Stroke Gap 2,ADBE Vector Stroke Offset",
"Can not add \"ADBE Vector Stroke Dash 9\" to Dashes"
])
);
}
#[test]
fn script_layer_comment_and_unnamed_marker_params_round_trip() {
let mut s = session();