diff --git a/core/src/avm1.rs b/core/src/avm1.rs index a7a9da2f4..b88de6617 100644 --- a/core/src/avm1.rs +++ b/core/src/avm1.rs @@ -1707,13 +1707,11 @@ impl<'gc> Avm1<'gc> { if target.is_empty() { context.active_clip = context.start_clip; context.target_clip = Some(context.start_clip); - context.target_path = target.into(); } else if let Some(clip) = Avm1::resolve_slash_path(context.start_clip, context.root, target) { context.target_clip = Some(clip); context.active_clip = clip; - context.target_path = target.into(); } else { log::warn!("SetTarget failed: {} not found", target); // TODO: Emulate AVM1 trace error message. @@ -1724,7 +1722,6 @@ impl<'gc> Avm1<'gc> { // fail silenty. context.target_clip = None; context.active_clip = context.root; - context.target_path = Value::Undefined; } let scope = self.current_stack_frame().unwrap().read().scope_cell(); diff --git a/core/src/avm1/script_object.rs b/core/src/avm1/script_object.rs index 6ab9156ec..76ffe416c 100644 --- a/core/src/avm1/script_object.rs +++ b/core/src/avm1/script_object.rs @@ -436,7 +436,6 @@ mod tests { start_clip: root, active_clip: root, target_clip: Some(root), - target_path: Value::Undefined, rng: &mut SmallRng::from_seed([0u8; 16]), action_queue: &mut crate::context::ActionQueue::new(), audio: &mut NullAudioBackend::new(), diff --git a/core/src/avm1/stage_object.rs b/core/src/avm1/stage_object.rs index 91c1522f6..17fe5840d 100644 --- a/core/src/avm1/stage_object.rs +++ b/core/src/avm1/stage_object.rs @@ -575,10 +575,9 @@ fn set_rotation<'gc>( fn target<'gc>( _avm: &mut Avm1<'gc>, _context: &mut UpdateContext<'_, 'gc, '_>, - _this: DisplayObject<'gc>, + this: DisplayObject<'gc>, ) -> Result, Error> { - log::warn!("Unimplemented property _target"); - Ok("".into()) + Ok(this.slash_path().into()) } fn frames_loaded<'gc>( diff --git a/core/src/avm1/test_utils.rs b/core/src/avm1/test_utils.rs index 0100a36af..1054af5c8 100644 --- a/core/src/avm1/test_utils.rs +++ b/core/src/avm1/test_utils.rs @@ -1,5 +1,5 @@ use crate::avm1::activation::Activation; -use crate::avm1::{Avm1, Object, UpdateContext, Value}; +use crate::avm1::{Avm1, Object, UpdateContext}; use crate::backend::audio::NullAudioBackend; use crate::backend::navigator::NullNavigatorBackend; use crate::backend::render::NullRenderer; @@ -32,7 +32,6 @@ where start_clip: root, active_clip: root, target_clip: Some(root), - target_path: Value::Undefined, rng: &mut SmallRng::from_seed([0u8; 16]), audio: &mut NullAudioBackend::new(), action_queue: &mut ActionQueue::new(), diff --git a/core/src/context.rs b/core/src/context.rs index c2d32e62c..efafc9078 100644 --- a/core/src/context.rs +++ b/core/src/context.rs @@ -77,13 +77,6 @@ pub struct UpdateContext<'a, 'gc, 'gc_context> { /// `target_clip` will reset to this value with `SetTarget ""` action. pub start_clip: DisplayObject<'gc>, - /// The last path string used by `tellTarget`. - /// Returned by `GetProperty`. - /// TODO: This should actually be built dynamically upon - /// request, but this requires us to implement auto-generated - /// _names ("instanceN" etc. for unnamed clips). - pub target_path: avm1::Value<'gc>, - /// The current set of system-specified prototypes to use when constructing /// new built-in objects. pub system_prototypes: avm1::SystemPrototypes<'gc>, diff --git a/core/src/display_object.rs b/core/src/display_object.rs index 552e1cb23..31dc16d17 100644 --- a/core/src/display_object.rs +++ b/core/src/display_object.rs @@ -521,6 +521,7 @@ pub trait TDisplayObject<'gc>: 'gc + Collect + Debug { fn set_alpha(&self, gc_context: MutationContext<'gc, '_>, value: f64); fn name(&self) -> Ref; fn set_name(&mut self, context: MutationContext<'gc, '_>, name: &str); + /// Returns the dot-syntax path to this display object, e.g. `_level0.foo.clip` fn path(&self) -> String { if let Some(parent) = self.parent() { @@ -532,6 +533,21 @@ pub trait TDisplayObject<'gc>: 'gc + Collect + Debug { self.name().to_string() } } + + /// Returns the Flash 4 slash-syntax path to this display object, e.g. `/foo/clip`. + /// Returned by the `_target` property in AVM1. + fn slash_path(&self) -> String { + if let Some(parent) = self.parent() { + let mut path = parent.slash_path(); + path.push_str("/"); + path.push_str(&*self.name()); + path + } else { + // The stage/root levels do not append their name in slash syntax. + "".to_string() + } + } + fn clip_depth(&self) -> Depth; fn set_clip_depth(&mut self, context: MutationContext<'gc, '_>, depth: Depth); fn parent(&self) -> Option>; diff --git a/core/src/player.rs b/core/src/player.rs index 4e7536fbc..35afede1b 100644 --- a/core/src/player.rs +++ b/core/src/player.rs @@ -1,4 +1,4 @@ -use crate::avm1::{Avm1, Value}; +use crate::avm1::Avm1; use crate::backend::{ audio::AudioBackend, navigator::NavigatorBackend, render::Letterbox, render::RenderBackend, }; @@ -594,7 +594,6 @@ impl start_clip: root, target_clip: Some(root), root, - target_path: Value::Undefined, system_prototypes: avm.prototypes().clone(), mouse_hovered_object, };