From bb053df30bcb230197549b49e6547467bea047f0 Mon Sep 17 00:00:00 2001 From: sleepycatcoding <131554884+sleepycatcoding@users.noreply.github.com> Date: Fri, 13 Oct 2023 01:34:06 +0300 Subject: [PATCH] avm2: Implement XMLList.parent --- core/src/avm2/globals/XMLList.as | 6 +++ core/src/avm2/globals/xml_list.rs | 39 ++++++++++++++++++- .../e4x/XMLList/e13_5_4_16/test.toml | 1 - 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/core/src/avm2/globals/XMLList.as b/core/src/avm2/globals/XMLList.as index dc49edd38..a5cb47d94 100644 --- a/core/src/avm2/globals/XMLList.as +++ b/core/src/avm2/globals/XMLList.as @@ -22,6 +22,7 @@ package { AS3 native function toXMLString():String; AS3 native function toString():String; AS3 native function comments():XMLList; + AS3 native function parent():*; AS3 native function processingInstructions(name:* = "*"):XMLList; // The following native methods are not declared in the documentation, @@ -110,6 +111,11 @@ package { return self.AS3::comments(); } + prototype.parent = function():* { + var self:XMLList = this; + return self.AS3::parent(); + } + prototype.toJSON = function(k:String):* { return "XMLList"; }; diff --git a/core/src/avm2/globals/xml_list.rs b/core/src/avm2/globals/xml_list.rs index f3ecb74b4..ae28e025f 100644 --- a/core/src/avm2/globals/xml_list.rs +++ b/core/src/avm2/globals/xml_list.rs @@ -7,7 +7,7 @@ use crate::avm2::{ e4x::{name_to_multiname, simple_content_to_string, E4XNode, E4XNodeKind}, error::type_error, multiname::Multiname, - object::{E4XOrXml, XmlListObject}, + object::{E4XOrXml, XmlListObject, XmlObject}, parameters::ParametersExt, string::AvmString, Activation, Error, Object, TObject, Value, @@ -342,6 +342,43 @@ pub fn comments<'gc>( Ok(XmlListObject::new(activation, nodes, Some(xml_list.into()), None).into()) } +// ECMA-357 13.5.4.17 XMLList.prototype.parent ( ) +pub fn parent<'gc>( + activation: &mut Activation<'_, 'gc>, + this: Object<'gc>, + _args: &[Value<'gc>], +) -> Result, Error<'gc>> { + let list = this.as_xml_list_object().unwrap(); + + // 1. If list.[[Length]] = 0, return undefined + if list.length() == 0 { + return Ok(Value::Undefined); + } + + // 2. Let parent = list[0].[[Parent]] + let parent = list.children()[0].node().parent(); + + // 3. For i = 1 to list.[[Length]]-1, if list[i].[[Parent]] is not equal to parent, return undefined + for child in list.children().iter().skip(1) { + let other = child.node().parent(); + + match (parent, other) { + (Some(v1), Some(v2)) if !E4XNode::ptr_eq(v1, v2) => { + return Ok(Value::Undefined); + } + (None, Some(_)) | (Some(_), None) => return Ok(Value::Undefined), + _ => {} + } + } + + // 4. Return parent + if let Some(parent) = parent { + Ok(XmlObject::new(parent, activation).into()) + } else { + Ok(Value::Undefined) + } +} + pub fn processing_instructions<'gc>( activation: &mut Activation<'_, 'gc>, this: Object<'gc>, diff --git a/tests/tests/swfs/from_avmplus/e4x/XMLList/e13_5_4_16/test.toml b/tests/tests/swfs/from_avmplus/e4x/XMLList/e13_5_4_16/test.toml index 29f3cef79..cf6123969 100644 --- a/tests/tests/swfs/from_avmplus/e4x/XMLList/e13_5_4_16/test.toml +++ b/tests/tests/swfs/from_avmplus/e4x/XMLList/e13_5_4_16/test.toml @@ -1,2 +1 @@ num_ticks = 1 -known_failure = true