avm2+tests: Fully implement XML.appendChild, add a test
This commit is contained in:
parent
cf8dde966f
commit
cf5c02ca1b
|
@ -314,22 +314,59 @@ pub fn append_child<'gc>(
|
|||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
let xml = this.as_xml_object().unwrap();
|
||||
|
||||
let child = args.get_object(activation, 0, "child")?;
|
||||
if let Some(child) = child.as_xml_object() {
|
||||
let child = args.get_value(0);
|
||||
if let Some(child) = child.as_object().and_then(|o| o.as_xml_object()) {
|
||||
xml.node()
|
||||
.append_child(activation.context.gc_context, *child.node())?;
|
||||
} else if let Some(list) = child.as_xml_list_object() {
|
||||
if list.target().is_some() {
|
||||
return Err("Cannot append XMLList with target".into());
|
||||
}
|
||||
} else if let Some(list) = child.as_object().and_then(|o| o.as_xml_list_object()) {
|
||||
for child in &*list.children() {
|
||||
xml.node()
|
||||
.append_child(activation.context.gc_context, *child.node())?;
|
||||
}
|
||||
} else {
|
||||
return Err(format!("Cannot append non-XML value {child:?}").into());
|
||||
// Appending a non-XML/XMLList object
|
||||
let last_child_name = if let E4XNodeKind::Element { children, .. } = &*xml.node().kind() {
|
||||
let num_children = children.len();
|
||||
|
||||
match num_children {
|
||||
0 => None,
|
||||
_ => children[num_children - 1].local_name(),
|
||||
}
|
||||
} else {
|
||||
// FIXME - figure out exactly when appending is allowed in FP,
|
||||
// and throw the proper AVM error.
|
||||
return Err(Error::RustError(
|
||||
format!(
|
||||
"Cannot append child {child:?} to node {:?}",
|
||||
xml.node().kind()
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
};
|
||||
Ok(Value::Undefined)
|
||||
|
||||
let text = child.coerce_to_string(activation)?;
|
||||
if let Some(last_child_name) = last_child_name {
|
||||
let element_node =
|
||||
E4XNode::element(activation.context.gc_context, last_child_name, *xml.node()); // Creating an element requires passing a parent node, unlike creating a text node
|
||||
|
||||
let text_node = E4XNode::text(activation.context.gc_context, text, None);
|
||||
|
||||
element_node
|
||||
.append_child(activation.context.gc_context, text_node)
|
||||
.expect("Appending to an element node should succeed");
|
||||
|
||||
xml.node()
|
||||
.append_child(activation.context.gc_context, element_node)?;
|
||||
} else {
|
||||
let node = E4XNode::text(activation.context.gc_context, text, None);
|
||||
// The text node will be parented in the append_child operation
|
||||
|
||||
xml.node()
|
||||
.append_child(activation.context.gc_context, node)?;
|
||||
}
|
||||
};
|
||||
|
||||
Ok(this.into())
|
||||
}
|
||||
|
||||
pub fn descendants<'gc>(
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package {
|
||||
import flash.display.MovieClip;
|
||||
|
||||
public class Test extends MovieClip {
|
||||
|
||||
public function Test() {
|
||||
XML.prettyPrinting = false;
|
||||
var xml:XML = <a><child1/><child2/></a>;
|
||||
trace(xml);
|
||||
var xmls:XMLList = (<root><child3/><child4/></root>).children();
|
||||
var appended:XML = xml.appendChild(xmls);
|
||||
trace(appended);
|
||||
trace(xml);
|
||||
trace(xml == appended);
|
||||
xml.child3 = "4";
|
||||
trace(xmls);
|
||||
xml.appendChild("qwerty");
|
||||
trace(xml);
|
||||
trace(xml.appendChild({"key":"value"}));
|
||||
var xml2:XML = <b>abcd</b>;
|
||||
trace(xml2.appendChild("text1").toXMLString());
|
||||
xml2 = <b></b>;
|
||||
trace(xml2.appendChild("text2").toXMLString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<a><child1/><child2/></a>
|
||||
<a><child1/><child2/><child3/><child4/></a>
|
||||
<a><child1/><child2/><child3/><child4/></a>
|
||||
true
|
||||
<child3>4</child3>
|
||||
<child4/>
|
||||
<a><child1/><child2/><child3>4</child3><child4/><child4>qwerty</child4></a>
|
||||
<a><child1/><child2/><child3>4</child3><child4/><child4>qwerty</child4><child4>[object Object]</child4></a>
|
||||
<b>abcdtext1</b>
|
||||
<b>text2</b>
|
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
num_frames = 1
|
Loading…
Reference in New Issue