diff --git a/core/src/avm2/globals/flash/xml/XMLNode.as b/core/src/avm2/globals/flash/xml/XMLNode.as
index bbf13f474..51a13028d 100644
--- a/core/src/avm2/globals/flash/xml/XMLNode.as
+++ b/core/src/avm2/globals/flash/xml/XMLNode.as
@@ -60,9 +60,30 @@ package flash.xml
return clone;
}
- public function removeNode() : void
- {
- stub_method("flash.xml.XMLNode", "removeNode");
+ public function removeNode(): void {
+ if (parentNode) {
+ if (parentNode.firstChild === this) {
+ parentNode.firstChild = nextSibling;
+ }
+ if (parentNode.lastChild === this) {
+ parentNode.lastChild = previousSibling;
+ }
+ var index = parentNode.childNodes.indexOf(this);
+ if (index > -1) {
+ parentNode.childNodes.removeAt(index);
+ }
+ }
+
+ if (previousSibling) {
+ previousSibling.nextSibling = nextSibling;
+ }
+ if (nextSibling) {
+ nextSibling.previousSibling = previousSibling;
+ }
+
+ parentNode = null;
+ previousSibling = null;
+ nextSibling = null;
}
public function insertBefore(node: XMLNode, before: XMLNode = null): void {
diff --git a/tests/tests/swfs/avm2/flash_xml_removeNode/Test.as b/tests/tests/swfs/avm2/flash_xml_removeNode/Test.as
new file mode 100644
index 000000000..4af1409f9
--- /dev/null
+++ b/tests/tests/swfs/avm2/flash_xml_removeNode/Test.as
@@ -0,0 +1,49 @@
+package {
+ import flash.display.Sprite;
+ public class Test extends Sprite { }
+}
+
+import flash.xml.XMLDocument;
+
+trace("///");
+var doc = new XMLDocument('a single child');
+trace("doc: " + doc);
+var single = doc.firstChild.firstChild;
+trace("single: " + single);
+single.removeNode();
+trace("/// After removal");
+trace("doc: " + doc);
+trace("single: " + single);
+trace("single.parentNode: " + single.parentNode);
+trace("single.nextSibling: " + single.nextSibling);
+trace("single.previousSibling: " + single.previousSibling);
+
+function test(index) {
+ var doc = new XMLDocument('')
+ trace("///")
+ trace("doc: " + doc);
+ var root = doc.firstChild;
+ var childNodes = root.childNodes;
+ var child = childNodes[index];
+ trace("root.childNodes[" + index + "]: " + child);
+ child.removeNode();
+ trace("/// After removal");
+ trace("doc: " + doc);
+ trace("child: " + child);
+ trace("child.parentNode: " + child.parentNode);
+ trace("child.nextSibling: " + child.nextSibling);
+ trace("child.previousSibling: " + child.previousSibling);
+
+ trace("root.firstChild: " + root.firstChild);
+ trace("root.lastChild: " + root.lastChild);
+
+ for (var i = 0; i < childNodes.length; i++) {
+ trace("childNodes[" + i + "]: " + childNodes[i]);
+ trace("childNodes[" + i + "].previousSibling: " + childNodes[i].previousSibling);
+ trace("childNodes[" + i + "].nextSibling: " + childNodes[i].nextSibling);
+ }
+}
+
+test(0);
+test(1);
+test(2);
diff --git a/tests/tests/swfs/avm2/flash_xml_removeNode/output.txt b/tests/tests/swfs/avm2/flash_xml_removeNode/output.txt
new file mode 100644
index 000000000..825f7dd74
--- /dev/null
+++ b/tests/tests/swfs/avm2/flash_xml_removeNode/output.txt
@@ -0,0 +1,60 @@
+///
+doc: a single child
+single: a single child
+/// After removal
+doc:
+single: a single child
+single.parentNode: null
+single.nextSibling: null
+single.previousSibling: null
+///
+doc:
+root.childNodes[0]:
+/// After removal
+doc:
+child:
+child.parentNode: null
+child.nextSibling: null
+child.previousSibling: null
+root.firstChild:
+root.lastChild:
+childNodes[0]:
+childNodes[0].previousSibling: null
+childNodes[0].nextSibling:
+childNodes[1]:
+childNodes[1].previousSibling:
+childNodes[1].nextSibling: null
+///
+doc:
+root.childNodes[1]:
+/// After removal
+doc:
+child:
+child.parentNode: null
+child.nextSibling: null
+child.previousSibling: null
+root.firstChild:
+root.lastChild:
+childNodes[0]:
+childNodes[0].previousSibling: null
+childNodes[0].nextSibling:
+childNodes[1]:
+childNodes[1].previousSibling:
+childNodes[1].nextSibling: null
+///
+doc:
+root.childNodes[2]:
+/// After removal
+doc:
+child:
+child.parentNode: null
+child.nextSibling: null
+child.previousSibling: null
+root.firstChild:
+root.lastChild:
+childNodes[0]:
+childNodes[0].previousSibling: null
+childNodes[0].nextSibling:
+childNodes[1]:
+childNodes[1].previousSibling:
+childNodes[1].nextSibling: null
diff --git a/tests/tests/swfs/avm2/flash_xml_removeNode/test.swf b/tests/tests/swfs/avm2/flash_xml_removeNode/test.swf
new file mode 100644
index 000000000..d5dfc5491
Binary files /dev/null and b/tests/tests/swfs/avm2/flash_xml_removeNode/test.swf differ
diff --git a/tests/tests/swfs/avm2/flash_xml_removeNode/test.toml b/tests/tests/swfs/avm2/flash_xml_removeNode/test.toml
new file mode 100644
index 000000000..dbee897f5
--- /dev/null
+++ b/tests/tests/swfs/avm2/flash_xml_removeNode/test.toml
@@ -0,0 +1 @@
+num_frames = 1