Merge pull request #1160 from nanox333/fix/1063-levels-alpha-name

# Conflicts:
#	crates/script/src/tests.rs
This commit is contained in:
Brandon Thomas committed 2026-10-13 04:35:20 -04:00
commit bb4972a886
2 files changed
+51 -16

No files matched your search

+33 -16
View File
@@ -434,6 +434,38 @@ fn alias(k: &str) -> Option<&'static str> {
})
}
/// How many groups below a property group a string key may search (#1063: Pro Levels2's Alpha
/// controls sit one group down, under Alpha).
const NESTED_CHILD_DEPTH: u8 = 3;
/// The child of `g` that a string key names. The direct children are searched first, then the
/// groups nested below them, up to `depth` levels.
fn find_child<'a>(l: &'a Layer, g: &'a PropGroup, k: &str, depth: u8) -> Option<&'a Node> {
let chain_of = |n: &Node| -> String {
let mut ch = if g.uid == l.props.uid { vec![] } else { chain(l, g.uid).unwrap_or_default() };
ch.push(n);
matchnames::node(&ch)
};
let lk = loose(k);
g.children
.iter()
.find(|n| chain_of(n) == k)
.or_else(|| g.children.iter().find(|n| n.name() == k))
.or_else(|| g.children.iter().find(|n| n.match_id() == k))
.or_else(|| g.children.iter().find(|n| n.name().eq_ignore_ascii_case(k)))
.or_else(|| g.children.iter().find(|n| loose(n.name()) == lk || loose(n.match_id()) == lk))
.or_else(|| alias(&lk).and_then(|m| g.children.iter().find(|n| n.match_id() == m)))
.or_else(|| {
if depth == 0 {
return None;
}
g.children.iter().find_map(|n| match n {
Node::Group(sub) => find_child(l, sub, k, depth - 1),
Node::Prop(_) => None,
})
})
}
fn child(s: &Session, a: &J) -> R {
let (_, c, l) = layer_of(s, a)?;
let uid = u(a, "uid").unwrap_or(0);
@@ -441,22 +473,7 @@ fn child(s: &Session, a: &J) -> R {
let key = a.get("key").cloned().unwrap_or(J::Null);
let found = match &key {
J::Number(n) => n.as_u64().and_then(|i| g.children.get((i as usize).checked_sub(1)?)),
J::String(k) => {
let chain_of = |n: &Node| -> String {
let mut ch = if uid == 0 || uid == l.props.uid { vec![] } else { chain(l, uid).unwrap_or_default() };
ch.push(n);
matchnames::node(&ch)
};
let lk = loose(k);
g.children
.iter()
.find(|n| chain_of(n) == *k)
.or_else(|| g.children.iter().find(|n| n.name() == k))
.or_else(|| g.children.iter().find(|n| n.match_id() == k))
.or_else(|| g.children.iter().find(|n| n.name().eq_ignore_ascii_case(k)))
.or_else(|| g.children.iter().find(|n| loose(n.name()) == lk || loose(n.match_id()) == lk))
.or_else(|| alias(&lk).and_then(|m| g.children.iter().find(|n| n.match_id() == m)))
}
J::String(k) => find_child(l, g, k, NESTED_CHILD_DEPTH),
_ => None,
};
match found {
+18
View File
@@ -1357,3 +1357,21 @@ fn earth_studio_style_script_keys_the_camera() {
assert_eq!(cam.props.prop("transform/rotationX").unwrap().keys[1].value, KV::Scalar(182.0));
assert_eq!(cam.props.prop("cameraOptions/zoom").unwrap().keys[1].value, KV::Scalar(1600.0));
}
/// Pro Levels2's Alpha controls sit one group down (under Alpha), so a script finds them by their
/// name on the effect as well as through the group (#1063).
#[test]
fn scripted_levels_alpha_controls_resolve_from_the_effect() {
let mut s = session();
let o = ok(
&mut s,
r#"
var c = app.project.items.addComp("Levels", 320, 180, 1, 3, 30);
var l = c.layers.addSolid([1, 0, 0], "S", 320, 180, 1);
var fx = l.property("ADBE Effect Parade").addProperty("ADBE Pro Levels2");
fx.property("Alpha Input White").setValue(0.5);
[fx.property("Alpha").property("Alpha Input White").value, fx.property("Alpha Input White").value]
"#,
);
assert_eq!(o.result, json!([0.5, 0.5]));
}