avm2: Add target property to XMLListObject
This commit is contained in:
parent
a3b95d9534
commit
4285d998dc
|
@ -2140,7 +2140,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
||||||
) => {
|
) => {
|
||||||
let mut children = value1.children().clone();
|
let mut children = value1.children().clone();
|
||||||
children.push(E4XOrXml::Xml(value2));
|
children.push(E4XOrXml::Xml(value2));
|
||||||
XmlListObject::new(self, children, None).into()
|
XmlListObject::new(self, children, None, None).into()
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
Value::Object(Object::XmlObject(value1)),
|
Value::Object(Object::XmlObject(value1)),
|
||||||
|
@ -2148,14 +2148,14 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
||||||
) => {
|
) => {
|
||||||
let mut children = vec![E4XOrXml::Xml(value1)];
|
let mut children = vec![E4XOrXml::Xml(value1)];
|
||||||
children.extend(value2.children().clone());
|
children.extend(value2.children().clone());
|
||||||
XmlListObject::new(self, children, None).into()
|
XmlListObject::new(self, children, None, None).into()
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
Value::Object(Object::XmlObject(value1)),
|
Value::Object(Object::XmlObject(value1)),
|
||||||
Value::Object(Object::XmlObject(value2)),
|
Value::Object(Object::XmlObject(value2)),
|
||||||
) => {
|
) => {
|
||||||
let children = vec![E4XOrXml::Xml(value1), E4XOrXml::Xml(value2)];
|
let children = vec![E4XOrXml::Xml(value1), E4XOrXml::Xml(value2)];
|
||||||
XmlListObject::new(self, children, None).into()
|
XmlListObject::new(self, children, None, None).into()
|
||||||
}
|
}
|
||||||
(value1, value2) => {
|
(value1, value2) => {
|
||||||
let prim_value1 = value1.coerce_to_primitive(None, self)?;
|
let prim_value1 = value1.coerce_to_primitive(None, self)?;
|
||||||
|
|
|
@ -224,7 +224,7 @@ pub fn child<'gc>(
|
||||||
} else {
|
} else {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
};
|
};
|
||||||
return Ok(XmlListObject::new(activation, children, None).into());
|
return Ok(XmlListObject::new(activation, children, None, None).into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +237,8 @@ pub fn child<'gc>(
|
||||||
Vec::new()
|
Vec::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(XmlListObject::new(activation, children, Some(xml.into())).into())
|
// FIXME: If name is not a number index, then we should call [[Get]] (get_property_local) with the name.
|
||||||
|
Ok(XmlListObject::new(activation, children, Some(xml.into()), Some(multiname)).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn child_index<'gc>(
|
pub fn child_index<'gc>(
|
||||||
|
@ -281,7 +282,14 @@ pub fn children<'gc>(
|
||||||
Vec::new()
|
Vec::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(XmlListObject::new(activation, children, Some(xml.into())).into())
|
// FIXME: Spec says to just call [[Get]] with * (any multiname).
|
||||||
|
Ok(XmlListObject::new(
|
||||||
|
activation,
|
||||||
|
children,
|
||||||
|
Some(xml.into()),
|
||||||
|
Some(Multiname::any(activation.gc())),
|
||||||
|
)
|
||||||
|
.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn copy<'gc>(
|
pub fn copy<'gc>(
|
||||||
|
@ -329,7 +337,7 @@ pub fn elements<'gc>(
|
||||||
Vec::new()
|
Vec::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(XmlListObject::new(activation, children, Some(xml.into())).into())
|
Ok(XmlListObject::new(activation, children, Some(xml.into()), None).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attributes<'gc>(
|
pub fn attributes<'gc>(
|
||||||
|
@ -344,7 +352,14 @@ pub fn attributes<'gc>(
|
||||||
Vec::new()
|
Vec::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(XmlListObject::new(activation, attributes, Some(xml.into())).into())
|
// FIXME: Spec/avmplus says to call [[Get]] with * attribute name (any attribute multiname).
|
||||||
|
Ok(XmlListObject::new(
|
||||||
|
activation,
|
||||||
|
attributes,
|
||||||
|
Some(xml.into()),
|
||||||
|
Some(Multiname::any_attribute(activation.gc())),
|
||||||
|
)
|
||||||
|
.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attribute<'gc>(
|
pub fn attribute<'gc>(
|
||||||
|
@ -364,7 +379,8 @@ pub fn attribute<'gc>(
|
||||||
Vec::new()
|
Vec::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(XmlListObject::new(activation, attributes, Some(xml.into())).into())
|
// FIXME: Spec/avmplus call [[Get]] with attribute name.
|
||||||
|
Ok(XmlListObject::new(activation, attributes, Some(xml.into()), Some(multiname)).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call_handler<'gc>(
|
pub fn call_handler<'gc>(
|
||||||
|
@ -510,9 +526,10 @@ pub fn descendants<'gc>(
|
||||||
let multiname = name_to_multiname(activation, &args[0], false)?;
|
let multiname = name_to_multiname(activation, &args[0], false)?;
|
||||||
let mut descendants = Vec::new();
|
let mut descendants = Vec::new();
|
||||||
xml.node().descendants(&multiname, &mut descendants);
|
xml.node().descendants(&multiname, &mut descendants);
|
||||||
Ok(XmlListObject::new(activation, descendants, Some(xml.into())).into())
|
Ok(XmlListObject::new(activation, descendants, None, None).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ECMA-357 13.4.4.37 XML.prototype.text ( )
|
||||||
pub fn text<'gc>(
|
pub fn text<'gc>(
|
||||||
activation: &mut Activation<'_, 'gc>,
|
activation: &mut Activation<'_, 'gc>,
|
||||||
this: Object<'gc>,
|
this: Object<'gc>,
|
||||||
|
@ -528,7 +545,9 @@ pub fn text<'gc>(
|
||||||
} else {
|
} else {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
};
|
};
|
||||||
Ok(XmlListObject::new(activation, nodes, Some(xml.into())).into())
|
// 1. Let list be a new XMLList with list.[[TargetObject]] = x and list.[[TargetProperty]] = null
|
||||||
|
// 3. Return list
|
||||||
|
Ok(XmlListObject::new(activation, nodes, Some(xml.into()), None).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn length<'gc>(
|
pub fn length<'gc>(
|
||||||
|
@ -559,6 +578,7 @@ pub fn has_simple_content<'gc>(
|
||||||
Ok(result.into())
|
Ok(result.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ECMA-357 13.4.4.9 XML.prototype.comments ( )
|
||||||
pub fn comments<'gc>(
|
pub fn comments<'gc>(
|
||||||
activation: &mut Activation<'_, 'gc>,
|
activation: &mut Activation<'_, 'gc>,
|
||||||
this: Object<'gc>,
|
this: Object<'gc>,
|
||||||
|
@ -575,9 +595,12 @@ pub fn comments<'gc>(
|
||||||
Vec::new()
|
Vec::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(XmlListObject::new(activation, comments, Some(xml.into())).into())
|
// 1. Let list be a new XMLList with list.[[TargetObject]] = x and list.[[TargetProperty]] = null
|
||||||
|
// 3. Return list
|
||||||
|
Ok(XmlListObject::new(activation, comments, Some(xml.into()), None).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ECMA-357 13.4.4.28 XML.prototype.processingInstructions ( [ name ] )
|
||||||
pub fn processing_instructions<'gc>(
|
pub fn processing_instructions<'gc>(
|
||||||
activation: &mut Activation<'_, 'gc>,
|
activation: &mut Activation<'_, 'gc>,
|
||||||
this: Object<'gc>,
|
this: Object<'gc>,
|
||||||
|
@ -598,7 +621,9 @@ pub fn processing_instructions<'gc>(
|
||||||
Vec::new()
|
Vec::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(XmlListObject::new(activation, nodes, Some(xml.into())).into())
|
// 3. Let list = a new XMLList with list.[[TargetObject]] = x and list.[[TargetProperty]] = null
|
||||||
|
// 5. Return list
|
||||||
|
Ok(XmlListObject::new(activation, nodes, Some(xml.into()), None).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
// ECMA-357 13.4.4.18 XML.prototype.insertChildAfter (child1, child2)
|
// ECMA-357 13.4.4.18 XML.prototype.insertChildAfter (child1, child2)
|
||||||
|
|
|
@ -6,6 +6,7 @@ pub use crate::avm2::object::xml_list_allocator;
|
||||||
use crate::avm2::{
|
use crate::avm2::{
|
||||||
e4x::{name_to_multiname, simple_content_to_string, E4XNode, E4XNodeKind},
|
e4x::{name_to_multiname, simple_content_to_string, E4XNode, E4XNodeKind},
|
||||||
error::type_error,
|
error::type_error,
|
||||||
|
multiname::Multiname,
|
||||||
object::{E4XOrXml, XmlListObject},
|
object::{E4XOrXml, XmlListObject},
|
||||||
parameters::ParametersExt,
|
parameters::ParametersExt,
|
||||||
string::AvmString,
|
string::AvmString,
|
||||||
|
@ -176,7 +177,7 @@ pub fn child<'gc>(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(XmlListObject::new(activation, sub_children, Some(list.into())).into())
|
Ok(XmlListObject::new(activation, sub_children, Some(list.into()), None).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn children<'gc>(
|
pub fn children<'gc>(
|
||||||
|
@ -192,7 +193,14 @@ pub fn children<'gc>(
|
||||||
sub_children.extend(children.iter().map(|node| E4XOrXml::E4X(*node)));
|
sub_children.extend(children.iter().map(|node| E4XOrXml::E4X(*node)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(XmlListObject::new(activation, sub_children, Some(list.into())).into())
|
// FIXME: This method should just call get_property_local with "*".
|
||||||
|
Ok(XmlListObject::new(
|
||||||
|
activation,
|
||||||
|
sub_children,
|
||||||
|
Some(list.into()),
|
||||||
|
Some(Multiname::any(activation.gc())),
|
||||||
|
)
|
||||||
|
.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn copy<'gc>(
|
pub fn copy<'gc>(
|
||||||
|
@ -227,7 +235,9 @@ pub fn attribute<'gc>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(XmlListObject::new(activation, sub_children, Some(list.into())).into())
|
|
||||||
|
// FIXME: This should just use get_property_local with an attribute Multiname.
|
||||||
|
Ok(XmlListObject::new(activation, sub_children, Some(list.into()), Some(multiname)).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attributes<'gc>(
|
pub fn attributes<'gc>(
|
||||||
|
@ -244,7 +254,14 @@ pub fn attributes<'gc>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(XmlListObject::new(activation, child_attrs, Some(list.into())).into())
|
// FIXME: This should just use get_property_local with an any attribute Multiname.
|
||||||
|
Ok(XmlListObject::new(
|
||||||
|
activation,
|
||||||
|
child_attrs,
|
||||||
|
Some(list.into()),
|
||||||
|
Some(Multiname::any_attribute(activation.gc())),
|
||||||
|
)
|
||||||
|
.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name<'gc>(
|
pub fn name<'gc>(
|
||||||
|
@ -299,7 +316,7 @@ pub fn text<'gc>(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(XmlListObject::new(activation, nodes, Some(xml_list.into())).into())
|
Ok(XmlListObject::new(activation, nodes, Some(xml_list.into()), None).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn comments<'gc>(
|
pub fn comments<'gc>(
|
||||||
|
@ -319,7 +336,7 @@ pub fn comments<'gc>(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(XmlListObject::new(activation, nodes, Some(xml_list.into())).into())
|
Ok(XmlListObject::new(activation, nodes, Some(xml_list.into()), None).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn processing_instructions<'gc>(
|
pub fn processing_instructions<'gc>(
|
||||||
|
@ -344,5 +361,5 @@ pub fn processing_instructions<'gc>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(XmlListObject::new(activation, nodes, Some(xml_list.into())).into())
|
Ok(XmlListObject::new(activation, nodes, Some(xml_list.into()), None).into())
|
||||||
}
|
}
|
||||||
|
|
|
@ -310,6 +310,16 @@ impl<'gc> Multiname<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Indicates the any attribute type (any attribute in any namespace).
|
||||||
|
pub fn any_attribute(mc: &Mutation<'gc>) -> Self {
|
||||||
|
Self {
|
||||||
|
ns: NamespaceSet::single(Namespace::any(mc)),
|
||||||
|
name: None,
|
||||||
|
param: None,
|
||||||
|
flags: MultinameFlags::ATTRIBUTE,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new(ns: Namespace<'gc>, name: impl Into<AvmString<'gc>>) -> Self {
|
pub fn new(ns: Namespace<'gc>, name: impl Into<AvmString<'gc>>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
ns: NamespaceSet::single(ns),
|
ns: NamespaceSet::single(ns),
|
||||||
|
|
|
@ -26,7 +26,8 @@ pub fn xml_list_allocator<'gc>(
|
||||||
children: Vec::new(),
|
children: Vec::new(),
|
||||||
// An XMLList created by 'new XMLList()' is not linked
|
// An XMLList created by 'new XMLList()' is not linked
|
||||||
// to any object
|
// to any object
|
||||||
target: None,
|
target_object: None,
|
||||||
|
target_property: None,
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
.into())
|
.into())
|
||||||
|
@ -52,7 +53,8 @@ impl<'gc> XmlListObject<'gc> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
activation: &mut Activation<'_, 'gc>,
|
activation: &mut Activation<'_, 'gc>,
|
||||||
children: Vec<E4XOrXml<'gc>>,
|
children: Vec<E4XOrXml<'gc>>,
|
||||||
target: Option<Object<'gc>>,
|
target_object: Option<Object<'gc>>,
|
||||||
|
target_property: Option<Multiname<'gc>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let base = ScriptObjectData::new(activation.context.avm2.classes().xml_list);
|
let base = ScriptObjectData::new(activation.context.avm2.classes().xml_list);
|
||||||
XmlListObject(GcCell::new(
|
XmlListObject(GcCell::new(
|
||||||
|
@ -60,7 +62,8 @@ impl<'gc> XmlListObject<'gc> {
|
||||||
XmlListObjectData {
|
XmlListObjectData {
|
||||||
base,
|
base,
|
||||||
children,
|
children,
|
||||||
target,
|
target_object,
|
||||||
|
target_property,
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -94,8 +97,12 @@ impl<'gc> XmlListObject<'gc> {
|
||||||
self.0.write(mc).children = children;
|
self.0.write(mc).children = children;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn target(&self) -> Option<Object<'gc>> {
|
pub fn target_object(&self) -> Option<Object<'gc>> {
|
||||||
self.0.read().target
|
self.0.read().target_object
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn target_property(&self) -> Option<Multiname<'gc>> {
|
||||||
|
self.0.read().target_property.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deep_copy(&self, activation: &mut Activation<'_, 'gc>) -> XmlListObject<'gc> {
|
pub fn deep_copy(&self, activation: &mut Activation<'_, 'gc>) -> XmlListObject<'gc> {
|
||||||
|
@ -104,7 +111,12 @@ impl<'gc> XmlListObject<'gc> {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|child| E4XOrXml::E4X(child.node().deep_copy(activation.context.gc_context)))
|
.map(|child| E4XOrXml::E4X(child.node().deep_copy(activation.context.gc_context)))
|
||||||
.collect();
|
.collect();
|
||||||
XmlListObject::new(activation, children, self.target())
|
XmlListObject::new(
|
||||||
|
activation,
|
||||||
|
children,
|
||||||
|
self.target_object(),
|
||||||
|
self.target_property(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn equals(
|
pub fn equals(
|
||||||
|
@ -160,7 +172,7 @@ impl<'gc> XmlListObject<'gc> {
|
||||||
let mut out = vec![];
|
let mut out = vec![];
|
||||||
out.extend(left.children().clone());
|
out.extend(left.children().clone());
|
||||||
out.extend(right.children().clone());
|
out.extend(right.children().clone());
|
||||||
Self::new(activation, out, None)
|
Self::new(activation, out, None, None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,7 +189,9 @@ pub struct XmlListObjectData<'gc> {
|
||||||
/// The XML or XMLList object that this list was created from.
|
/// The XML or XMLList object that this list was created from.
|
||||||
/// If `Some`, then modifications to this list are reflected
|
/// If `Some`, then modifications to this list are reflected
|
||||||
/// in the original object.
|
/// in the original object.
|
||||||
target: Option<Object<'gc>>,
|
target_object: Option<Object<'gc>>,
|
||||||
|
|
||||||
|
target_property: Option<Multiname<'gc>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Holds either an `E4XNode` or an `XmlObject`. This can be converted
|
/// Holds either an `E4XNode` or an `XmlObject`. This can be converted
|
||||||
|
@ -260,11 +274,7 @@ impl<'gc> TObject<'gc> for XmlListObject<'gc> {
|
||||||
for child in self.0.read().children.iter() {
|
for child in self.0.read().children.iter() {
|
||||||
child.node().descendants(multiname, &mut descendants);
|
child.node().descendants(multiname, &mut descendants);
|
||||||
}
|
}
|
||||||
Some(XmlListObject::new(
|
Some(XmlListObject::new(activation, descendants, None, None))
|
||||||
activation,
|
|
||||||
descendants,
|
|
||||||
Some((*self).into()),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_property_local(
|
fn get_property_local(
|
||||||
|
@ -309,7 +319,13 @@ impl<'gc> TObject<'gc> for XmlListObject<'gc> {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Ok(XmlListObject::new(activation, matched_children, Some(self.into())).into())
|
Ok(XmlListObject::new(
|
||||||
|
activation,
|
||||||
|
matched_children,
|
||||||
|
Some(self.into()),
|
||||||
|
Some(name.clone()),
|
||||||
|
)
|
||||||
|
.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_property_local(
|
fn call_property_local(
|
||||||
|
@ -377,7 +393,7 @@ impl<'gc> TObject<'gc> for XmlListObject<'gc> {
|
||||||
if let Some(local_name) = name.local_name() {
|
if let Some(local_name) = name.local_name() {
|
||||||
if let Ok(index) = local_name.parse::<usize>() {
|
if let Ok(index) = local_name.parse::<usize>() {
|
||||||
// 2.a. If x.[[TargetObject]] is not null
|
// 2.a. If x.[[TargetObject]] is not null
|
||||||
if let Some(target) = write.target {
|
if let Some(target) = write.target_object {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"Modifying an XMLList object is not yet implemented: target {:?}",
|
"Modifying an XMLList object is not yet implemented: target {:?}",
|
||||||
target
|
target
|
||||||
|
|
|
@ -183,11 +183,7 @@ impl<'gc> TObject<'gc> for XmlObject<'gc> {
|
||||||
) -> Option<XmlListObject<'gc>> {
|
) -> Option<XmlListObject<'gc>> {
|
||||||
let mut descendants = Vec::new();
|
let mut descendants = Vec::new();
|
||||||
self.0.read().node.descendants(multiname, &mut descendants);
|
self.0.read().node.descendants(multiname, &mut descendants);
|
||||||
Some(XmlListObject::new(
|
Some(XmlListObject::new(activation, descendants, None, None))
|
||||||
activation,
|
|
||||||
descendants,
|
|
||||||
Some((*self).into()),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_property_local(
|
fn get_property_local(
|
||||||
|
@ -236,7 +232,13 @@ impl<'gc> TObject<'gc> for XmlObject<'gc> {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
return Ok(XmlListObject::new(activation, matched_children, Some(self.into())).into());
|
return Ok(XmlListObject::new(
|
||||||
|
activation,
|
||||||
|
matched_children,
|
||||||
|
Some(self.into()),
|
||||||
|
Some(name.clone()),
|
||||||
|
)
|
||||||
|
.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_property_local(
|
fn call_property_local(
|
||||||
|
|
Loading…
Reference in New Issue