Skip to content

Commit 5b19ece

Browse files
sleepycatcodingevilpie
authored andcommitted
avm2: Implement XML.setLocalName
1 parent e0a22b5 commit 5b19ece

File tree

5 files changed

+67
-7
lines changed

5 files changed

+67
-7
lines changed

core/src/avm2/e4x.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,11 @@ impl<'gc> E4XNode<'gc> {
200200
)
201201
}
202202

203+
/// Returns true when the node is a comment (E4XNodeKind::Comment)
204+
pub fn is_comment(&self) -> bool {
205+
matches!(self.0.read().kind, E4XNodeKind::Comment(_))
206+
}
207+
203208
/// Returns an iterator that yields ancestor nodes (including itself).
204209
pub fn ancestors(self) -> impl Iterator<Item = E4XNode<'gc>> {
205210
iterators::AnscIter::for_node(self)

core/src/avm2/error.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,24 @@ pub fn make_error_1089<'gc>(activation: &mut Activation<'_, 'gc>) -> Error<'gc>
231231
}
232232
}
233233

234+
#[inline(never)]
235+
#[cold]
236+
pub fn make_error_1117<'gc>(
237+
activation: &mut Activation<'_, 'gc>,
238+
name: AvmString<'gc>,
239+
) -> Error<'gc> {
240+
let err = type_error(
241+
activation,
242+
&format!("Error #1117: Invalid XML name: {}.", name.as_wstr()),
243+
1117,
244+
);
245+
246+
match err {
247+
Ok(err) => Error::AvmError(err),
248+
Err(err) => err,
249+
}
250+
}
251+
234252
#[inline(never)]
235253
#[cold]
236254
pub fn make_error_1118<'gc>(activation: &mut Activation<'_, 'gc>) -> Error<'gc> {

core/src/avm2/globals/XML.as

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ package {
8585
// NOTE: Docs lie, value can be anything not just XML.
8686
AS3 native function replace(propertyName:Object, value:*):XML;
8787
AS3 native function setChildren(value:Object):XML;
88+
AS3 native function setLocalName(name:*):void;
8889

8990
AS3 function valueOf():XML {
9091
return this;
@@ -255,6 +256,11 @@ package {
255256
return self.AS3::setChildren(value);
256257
}
257258

259+
prototype.setLocalName = function(name:*):void {
260+
var self:XML = this;
261+
self.AS3::setLocalName(name);
262+
}
263+
258264
public static const length:int = 1;
259265
}
260266
}

core/src/avm2/globals/xml.rs

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use crate::avm2::api_version::ApiVersion;
44
use crate::avm2::e4x::{name_to_multiname, E4XNode, E4XNodeKind};
5-
use crate::avm2::error::type_error;
5+
use crate::avm2::error::{make_error_1117, type_error};
66
pub use crate::avm2::object::xml_allocator;
77
use crate::avm2::object::{
88
E4XOrXml, NamespaceObject, QNameObject, TObject, XmlListObject, XmlObject,
@@ -166,11 +166,7 @@ pub fn set_name<'gc>(
166166

167167
let is_name_valid = crate::avm2::e4x::is_xml_name(new_name);
168168
if !is_name_valid {
169-
return Err(Error::AvmError(type_error(
170-
activation,
171-
&format!("Error #1117: Invalid XML name: {}.", new_name),
172-
1117,
173-
)?));
169+
return Err(make_error_1117(activation, new_name));
174170
}
175171

176172
node.set_local_name(new_name, activation.context.gc_context);
@@ -830,6 +826,42 @@ pub fn set_children<'gc>(
830826
Ok(xml.into())
831827
}
832828

829+
// ECMA-357 13.4.4.34 XML.prototype.setLocalName ( name )
830+
pub fn set_local_name<'gc>(
831+
activation: &mut Activation<'_, 'gc>,
832+
this: Object<'gc>,
833+
args: &[Value<'gc>],
834+
) -> Result<Value<'gc>, Error<'gc>> {
835+
let xml = this.as_xml_object().unwrap();
836+
let node = xml.node();
837+
let name = args.get_value(0);
838+
839+
// 1. If x.[[Class]] ∈ {"text", "comment"}, return
840+
if node.is_text() || node.is_comment() {
841+
return Ok(Value::Undefined);
842+
}
843+
844+
// 2. If (Type(name) is Object) and (name.[[Class]] == "QName")
845+
let name = if let Some(qname) = name.as_object().and_then(|x| x.as_qname_object()) {
846+
// 2.a. Let name = name.localName
847+
qname.local_name()
848+
// 3. Else
849+
} else {
850+
// 3.a. Let name = ToString(name)
851+
name.coerce_to_string(activation)?
852+
};
853+
854+
// NOTE: avmplus check, not in spec.
855+
if !crate::avm2::e4x::is_xml_name(name) {
856+
return Err(make_error_1117(activation, name));
857+
}
858+
859+
// 4. Let x.[[Name]].localName = name
860+
node.set_local_name(name, activation.gc());
861+
862+
Ok(Value::Undefined)
863+
}
864+
833865
pub fn set_notification<'gc>(
834866
activation: &mut Activation<'_, 'gc>,
835867
this: Object<'gc>,
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
num_ticks = 1
2-
known_failure = true

0 commit comments

Comments
 (0)