avm2: Implement ApplicationDomain::getQualifiedDefinitionNames

This commit is contained in:
friedkeenan 2023-05-03 20:47:33 -05:00 committed by Aaron Hill
parent 8d96626026
commit 24e0e0102c
3 changed files with 47 additions and 1 deletions

View File

@ -219,6 +219,15 @@ impl<'gc> Domain<'gc> {
res
}
pub fn get_defined_names(&self) -> Vec<QName<'gc>> {
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.

View File

@ -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.<String>;
}
}

View File

@ -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<Object<'gc>>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, 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>,