avm1: Add include_hidden: bool to get_keys()
This commit is contained in:
parent
310b03b570
commit
afdd617d29
|
@ -1022,12 +1022,12 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
|||
match object {
|
||||
Value::MovieClip(_) => {
|
||||
let ob = object.coerce_to_object(self);
|
||||
for k in ob.get_keys(self).into_iter().rev() {
|
||||
for k in ob.get_keys(self, false).into_iter().rev() {
|
||||
self.stack_push(k.into());
|
||||
}
|
||||
}
|
||||
Value::Object(ob) => {
|
||||
for k in ob.get_keys(self).into_iter().rev() {
|
||||
for k in ob.get_keys(self, false).into_iter().rev() {
|
||||
self.stack_push(k.into());
|
||||
}
|
||||
}
|
||||
|
@ -1044,11 +1044,11 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
|||
|
||||
if let Value::MovieClip(_) = value {
|
||||
let object = value.coerce_to_object(self);
|
||||
for k in object.get_keys(self).into_iter().rev() {
|
||||
for k in object.get_keys(self, false).into_iter().rev() {
|
||||
self.stack_push(k.into());
|
||||
}
|
||||
} else if let Value::Object(object) = value {
|
||||
for k in object.get_keys(self).into_iter().rev() {
|
||||
for k in object.get_keys(self, false).into_iter().rev() {
|
||||
self.stack_push(k.into());
|
||||
}
|
||||
} else {
|
||||
|
@ -2445,7 +2445,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
|||
/// WARNING: This does not support user defined virtual properties!
|
||||
pub fn object_into_form_values(&mut self, object: Object<'gc>) -> IndexMap<String, String> {
|
||||
let mut form_values = IndexMap::new();
|
||||
let keys = object.get_keys(self);
|
||||
let keys = object.get_keys(self, false);
|
||||
|
||||
for k in keys {
|
||||
let v = object.get(k, self);
|
||||
|
|
|
@ -119,7 +119,7 @@ impl<'a> VariableDumper<'a> {
|
|||
object: &Object<'gc>,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
) {
|
||||
let keys = object.get_keys(activation);
|
||||
let keys = object.get_keys(activation, false);
|
||||
if keys.is_empty() {
|
||||
self.output.push_str(" {}");
|
||||
} else {
|
||||
|
@ -166,7 +166,7 @@ impl<'a> VariableDumper<'a> {
|
|||
object: &Object<'gc>,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
) {
|
||||
let keys = object.get_keys(activation);
|
||||
let keys = object.get_keys(activation, false);
|
||||
if keys.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -171,7 +171,7 @@ fn send<'gc>(
|
|||
use indexmap::IndexMap;
|
||||
|
||||
let mut form_values = IndexMap::new();
|
||||
let keys = this.get_keys(activation);
|
||||
let keys = this.get_keys(activation, false);
|
||||
|
||||
for k in keys {
|
||||
let v = this.get(k, activation);
|
||||
|
@ -226,7 +226,7 @@ fn to_string<'gc>(
|
|||
use indexmap::IndexMap;
|
||||
|
||||
let mut form_values = IndexMap::new();
|
||||
let keys = this.get_keys(activation);
|
||||
let keys = this.get_keys(activation, false);
|
||||
|
||||
for k in keys {
|
||||
let v = this.get(k, activation);
|
||||
|
|
|
@ -102,7 +102,7 @@ fn recursive_serialize<'gc>(
|
|||
elements: &mut Vec<Element>,
|
||||
) {
|
||||
// Reversed to match flash player ordering
|
||||
for element_name in obj.get_keys(activation).into_iter().rev() {
|
||||
for element_name in obj.get_keys(activation, false).into_iter().rev() {
|
||||
if let Ok(elem) = obj.get(element_name, activation) {
|
||||
if let Some(v) = serialize_value(activation, elem) {
|
||||
elements.push(Element::new(element_name.to_utf8_lossy(), v));
|
||||
|
@ -439,7 +439,7 @@ pub fn clear<'gc>(
|
|||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
let data = this.get("data", activation)?.coerce_to_object(activation);
|
||||
|
||||
for k in &data.get_keys(activation) {
|
||||
for k in &data.get_keys(activation, false) {
|
||||
data.delete(activation, *k);
|
||||
}
|
||||
|
||||
|
|
|
@ -477,8 +477,13 @@ pub trait TObject<'gc>: 'gc + Collect + Into<Object<'gc>> + Clone + Copy {
|
|||
}
|
||||
|
||||
/// Enumerate the object.
|
||||
fn get_keys(&self, activation: &mut Activation<'_, 'gc>) -> Vec<AvmString<'gc>> {
|
||||
self.raw_script_object().get_keys(activation)
|
||||
fn get_keys(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
include_hidden: bool,
|
||||
) -> Vec<AvmString<'gc>> {
|
||||
self.raw_script_object()
|
||||
.get_keys(activation, include_hidden)
|
||||
}
|
||||
|
||||
/// Enumerate all interfaces implemented by this object.
|
||||
|
|
|
@ -444,9 +444,13 @@ impl<'gc> TObject<'gc> for ScriptObject<'gc> {
|
|||
}
|
||||
|
||||
/// Enumerate the object.
|
||||
fn get_keys(&self, activation: &mut Activation<'_, 'gc>) -> Vec<AvmString<'gc>> {
|
||||
fn get_keys(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
include_hidden: bool,
|
||||
) -> Vec<AvmString<'gc>> {
|
||||
let proto_keys = if let Value::Object(proto) = self.proto(activation) {
|
||||
proto.get_keys(activation)
|
||||
proto.get_keys(activation, include_hidden)
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
|
@ -461,7 +465,7 @@ impl<'gc> TObject<'gc> for ScriptObject<'gc> {
|
|||
|
||||
// Then our own keys.
|
||||
out_keys.extend(self.0.read().properties.iter().filter_map(move |(k, p)| {
|
||||
if p.is_enumerable() {
|
||||
if include_hidden || p.is_enumerable() {
|
||||
Some(k)
|
||||
} else {
|
||||
None
|
||||
|
@ -756,7 +760,7 @@ mod tests {
|
|||
Attribute::DONT_ENUM,
|
||||
);
|
||||
|
||||
let keys: Vec<_> = object.get_keys(activation);
|
||||
let keys: Vec<_> = object.get_keys(activation, false);
|
||||
assert_eq!(keys.len(), 2);
|
||||
assert!(keys.contains(&"stored".into()));
|
||||
assert!(!keys.contains(&"stored_hidden".into()));
|
||||
|
|
|
@ -330,11 +330,15 @@ impl<'gc> TObject<'gc> for StageObject<'gc> {
|
|||
false
|
||||
}
|
||||
|
||||
fn get_keys(&self, activation: &mut Activation<'_, 'gc>) -> Vec<AvmString<'gc>> {
|
||||
fn get_keys(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
include_hidden: bool,
|
||||
) -> Vec<AvmString<'gc>> {
|
||||
// Keys from the underlying object are listed first, followed by
|
||||
// child display objects in order from highest depth to lowest depth.
|
||||
let obj = self.0.read();
|
||||
let mut keys = obj.base.get_keys(activation);
|
||||
let mut keys = obj.base.get_keys(activation, include_hidden);
|
||||
|
||||
if let Some(ctr) = obj.display_object.as_container() {
|
||||
// Button/MovieClip children are included in key list.
|
||||
|
|
|
@ -223,7 +223,11 @@ impl<'gc> TObject<'gc> for SuperObject<'gc> {
|
|||
false
|
||||
}
|
||||
|
||||
fn get_keys(&self, _activation: &mut Activation<'_, 'gc>) -> Vec<AvmString<'gc>> {
|
||||
fn get_keys(
|
||||
&self,
|
||||
_activation: &mut Activation<'_, 'gc>,
|
||||
_include_hidden: bool,
|
||||
) -> Vec<AvmString<'gc>> {
|
||||
vec![]
|
||||
}
|
||||
|
||||
|
|
|
@ -1980,7 +1980,11 @@ impl<'gc> MovieClip<'gc> {
|
|||
if let Some(init_object) = init_object {
|
||||
// AVM1 sets keys in reverse order (compared to enumeration order).
|
||||
// This behavior is visible to setters, and some SWFs depend on it.
|
||||
for key in init_object.get_keys(&mut activation).into_iter().rev() {
|
||||
for key in init_object
|
||||
.get_keys(&mut activation, false)
|
||||
.into_iter()
|
||||
.rev()
|
||||
{
|
||||
if let Ok(value) = init_object.get(key, &mut activation) {
|
||||
let _ = object.set(key, value, &mut activation);
|
||||
}
|
||||
|
@ -2011,7 +2015,7 @@ impl<'gc> MovieClip<'gc> {
|
|||
self.into(),
|
||||
);
|
||||
|
||||
for key in init_object.get_keys(&mut activation) {
|
||||
for key in init_object.get_keys(&mut activation, false) {
|
||||
if let Ok(value) = init_object.get(key, &mut activation) {
|
||||
let _ = object.set(key, value, &mut activation);
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ impl Value {
|
|||
.collect();
|
||||
Value::List(values?)
|
||||
} else {
|
||||
let keys = object.get_keys(activation);
|
||||
let keys = object.get_keys(activation, false);
|
||||
let mut values = BTreeMap::new();
|
||||
for key in keys {
|
||||
let value = object.get(key, activation)?;
|
||||
|
|
Loading…
Reference in New Issue