Partly implement XML child and elements
This makes #3294 (rollercoaster-creator-2) fully playable. Missing is any (*) matching for child()/elements() and the existing attributes() method. Also missing is support for number indexes with child().
This commit is contained in:
parent
ea3fdfa27e
commit
f53c83cfa4
|
@ -10,7 +10,9 @@ package {
|
||||||
AS3 native function name():Object;
|
AS3 native function name():Object;
|
||||||
AS3 native function localName():Object;
|
AS3 native function localName():Object;
|
||||||
AS3 native function toXMLString():String;
|
AS3 native function toXMLString():String;
|
||||||
|
AS3 native function child(name:Object):XMLList;
|
||||||
AS3 native function children():XMLList;
|
AS3 native function children():XMLList;
|
||||||
|
AS3 native function elements(name:*):XMLList;
|
||||||
AS3 native function attributes():XMLList;
|
AS3 native function attributes():XMLList;
|
||||||
AS3 native function attribute(name:*):XMLList;
|
AS3 native function attribute(name:*):XMLList;
|
||||||
|
|
||||||
|
@ -36,11 +38,21 @@ package {
|
||||||
return self.AS3::toXMLString();
|
return self.AS3::toXMLString();
|
||||||
};
|
};
|
||||||
|
|
||||||
prototype.children = function():String {
|
prototype.child = function(name:Object):XMLList {
|
||||||
|
var self:XML = this;
|
||||||
|
return self.AS3::child(name);
|
||||||
|
};
|
||||||
|
|
||||||
|
prototype.children = function():XMLList {
|
||||||
var self:XML = this;
|
var self:XML = this;
|
||||||
return self.AS3::children();
|
return self.AS3::children();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
prototype.elements = function(name:*):XMLList {
|
||||||
|
var self:XML = this;
|
||||||
|
return self.AS3::elements(name);
|
||||||
|
}
|
||||||
|
|
||||||
prototype.toString = function():String {
|
prototype.toString = function():String {
|
||||||
if (this === prototype) {
|
if (this === prototype) {
|
||||||
return "";
|
return "";
|
||||||
|
|
|
@ -88,6 +88,50 @@ pub fn to_xml_string<'gc>(
|
||||||
Ok(Value::String(node.xml_to_xml_string(activation)?))
|
Ok(Value::String(node.xml_to_xml_string(activation)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn name_to_multiname<'gc>(
|
||||||
|
activation: &mut Activation<'_, 'gc>,
|
||||||
|
name: &Value<'gc>,
|
||||||
|
) -> Result<Multiname<'gc>, Error<'gc>> {
|
||||||
|
Ok(match name {
|
||||||
|
Value::String(s) => Multiname::new(activation.avm2().public_namespace, *s),
|
||||||
|
Value::Object(o) => {
|
||||||
|
if let Some(qname) = o.as_qname_object() {
|
||||||
|
qname.name().clone()
|
||||||
|
} else {
|
||||||
|
Multiname::new(
|
||||||
|
activation.avm2().public_namespace,
|
||||||
|
name.coerce_to_string(activation)?,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => Multiname::new(
|
||||||
|
activation.avm2().public_namespace,
|
||||||
|
name.coerce_to_string(activation)?,
|
||||||
|
),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn child<'gc>(
|
||||||
|
activation: &mut Activation<'_, 'gc>,
|
||||||
|
this: Option<Object<'gc>>,
|
||||||
|
args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
let xml = this.unwrap().as_xml_object().unwrap();
|
||||||
|
let multiname = name_to_multiname(activation, &args[0])?;
|
||||||
|
// FIXME: Support numerical indexes.
|
||||||
|
let children = if let E4XNodeKind::Element { children, .. } = &*xml.node().kind() {
|
||||||
|
children
|
||||||
|
.iter()
|
||||||
|
.filter(|node| node.matches_name(&multiname))
|
||||||
|
.map(|node| E4XOrXml::E4X(*node))
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(XmlListObject::new(activation, children, Some(xml.into())).into())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn children<'gc>(
|
pub fn children<'gc>(
|
||||||
activation: &mut Activation<'_, 'gc>,
|
activation: &mut Activation<'_, 'gc>,
|
||||||
this: Option<Object<'gc>>,
|
this: Option<Object<'gc>>,
|
||||||
|
@ -103,6 +147,25 @@ pub fn children<'gc>(
|
||||||
Ok(XmlListObject::new(activation, children, Some(xml.into())).into())
|
Ok(XmlListObject::new(activation, children, Some(xml.into())).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn elements<'gc>(
|
||||||
|
activation: &mut Activation<'_, 'gc>,
|
||||||
|
this: Option<Object<'gc>>,
|
||||||
|
_args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
let xml = this.unwrap().as_xml_object().unwrap();
|
||||||
|
let children = if let E4XNodeKind::Element { children, .. } = &*xml.node().kind() {
|
||||||
|
children
|
||||||
|
.iter()
|
||||||
|
.filter(|node| matches!(&*node.kind(), E4XNodeKind::Element { .. }))
|
||||||
|
.map(|node| E4XOrXml::E4X(*node))
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(XmlListObject::new(activation, children, Some(xml.into())).into())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn attributes<'gc>(
|
pub fn attributes<'gc>(
|
||||||
activation: &mut Activation<'_, 'gc>,
|
activation: &mut Activation<'_, 'gc>,
|
||||||
this: Option<Object<'gc>>,
|
this: Option<Object<'gc>>,
|
||||||
|
@ -126,25 +189,7 @@ pub fn attribute<'gc>(
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
let this = this.unwrap();
|
let this = this.unwrap();
|
||||||
let xml = this.as_xml_object().unwrap();
|
let xml = this.as_xml_object().unwrap();
|
||||||
let name = args[0];
|
let multiname = name_to_multiname(activation, &args[0])?;
|
||||||
let multiname = match name {
|
|
||||||
Value::String(s) => Multiname::new(activation.avm2().public_namespace, s),
|
|
||||||
Value::Object(o) => {
|
|
||||||
if let Some(qname) = o.as_qname_object() {
|
|
||||||
qname.name().clone()
|
|
||||||
} else {
|
|
||||||
Multiname::new(
|
|
||||||
activation.avm2().public_namespace,
|
|
||||||
name.coerce_to_string(activation)?,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => Multiname::new(
|
|
||||||
activation.avm2().public_namespace,
|
|
||||||
name.coerce_to_string(activation)?,
|
|
||||||
),
|
|
||||||
};
|
|
||||||
|
|
||||||
let attribute = if let E4XNodeKind::Element { attributes, .. } = &*xml.node().kind() {
|
let attribute = if let E4XNodeKind::Element { attributes, .. } = &*xml.node().kind() {
|
||||||
attributes
|
attributes
|
||||||
.iter()
|
.iter()
|
||||||
|
|
Loading…
Reference in New Issue