diff --git a/core/src/avm2/domain.rs b/core/src/avm2/domain.rs index da88a3510..ceae63fc9 100644 --- a/core/src/avm2/domain.rs +++ b/core/src/avm2/domain.rs @@ -219,6 +219,15 @@ impl<'gc> Domain<'gc> { res } + pub fn get_defined_names(&self) -> Vec> { + self.0 + .read() + .defs + .iter() + .map(|(name, namespace, _)| QName::new(namespace, name)) + .collect() + } + /// Export a definition from a script into the current application domain. /// /// This does nothing if the definition already exists. diff --git a/core/src/avm2/globals/flash/system/ApplicationDomain.as b/core/src/avm2/globals/flash/system/ApplicationDomain.as index 216bfa9cb..21d0f38a2 100644 --- a/core/src/avm2/globals/flash/system/ApplicationDomain.as +++ b/core/src/avm2/globals/flash/system/ApplicationDomain.as @@ -17,5 +17,7 @@ package flash.system { public native function getDefinition(name:String):Object; public native function hasDefinition(name:String):Boolean; + + public native function getQualifiedDefinitionNames():Vector.; } } diff --git a/core/src/avm2/globals/flash/system/application_domain.rs b/core/src/avm2/globals/flash/system/application_domain.rs index b39bf2a8c..7ece4a054 100644 --- a/core/src/avm2/globals/flash/system/application_domain.rs +++ b/core/src/avm2/globals/flash/system/application_domain.rs @@ -1,9 +1,10 @@ //! `flash.system.ApplicationDomain` class use crate::avm2::activation::Activation; -use crate::avm2::object::{DomainObject, Object, TObject}; +use crate::avm2::object::{DomainObject, Object, TObject, VectorObject}; use crate::avm2::parameters::ParametersExt; use crate::avm2::value::Value; +use crate::avm2::vector::VectorStorage; use crate::avm2::QName; use crate::avm2::{Domain, Error}; @@ -102,6 +103,40 @@ pub fn has_definition<'gc>( Ok(Value::Undefined) } +/// 'getQualifiedDefinitionNames' method. +/// +/// NOTE: Normally only available in Flash Player 11.3+. +pub fn get_qualified_definition_names<'gc>( + activation: &mut Activation<'_, 'gc>, + this: Option>, + _args: &[Value<'gc>], +) -> Result, Error<'gc>> { + if let Some(appdomain) = this.and_then(|this| this.as_application_domain()) { + // NOTE: According to the docs of 'getQualifiedDeinitionNames', + // it is able to throw a 'SecurityError' if "The definition belongs + // to a domain to which the calling code does not have access." + // + // We do not implement this. + + let storage = VectorStorage::from_values( + appdomain + .get_defined_names() + .iter() + .filter(|name| !name.namespace().is_private()) + .map(|name| Value::String(name.to_qualified_name(activation.context.gc_context))) + .collect(), + false, + activation.avm2().classes().string, + ); + + let name_array = VectorObject::from_vector(storage, activation)?; + + return Ok(name_array.into()); + } + + Ok(Value::Undefined) +} + /// `domainMemory` property setter pub fn set_domain_memory<'gc>( activation: &mut Activation<'_, 'gc>,