Add XMLNode class and constructor impl
This commit is contained in:
parent
6a65e984ae
commit
554f0dc1e5
|
@ -20,6 +20,7 @@ mod object;
|
||||||
mod sound;
|
mod sound;
|
||||||
mod stage;
|
mod stage;
|
||||||
pub(crate) mod text_field;
|
pub(crate) mod text_field;
|
||||||
|
mod xml;
|
||||||
|
|
||||||
#[allow(non_snake_case, unused_must_use)] //can't use errors yet
|
#[allow(non_snake_case, unused_must_use)] //can't use errors yet
|
||||||
pub fn getURL<'a, 'gc>(
|
pub fn getURL<'a, 'gc>(
|
||||||
|
@ -172,6 +173,8 @@ pub fn create_globals<'gc>(
|
||||||
let array_proto: Object<'gc> = array::create_proto(gc_context, object_proto, function_proto);
|
let array_proto: Object<'gc> = array::create_proto(gc_context, object_proto, function_proto);
|
||||||
|
|
||||||
let color_proto: Object<'gc> = color::create_proto(gc_context, object_proto, function_proto);
|
let color_proto: Object<'gc> = color::create_proto(gc_context, object_proto, function_proto);
|
||||||
|
let xmlnode_proto: Object<'gc> =
|
||||||
|
xml::create_xmlnode_proto(gc_context, object_proto, function_proto);
|
||||||
|
|
||||||
//TODO: These need to be constructors and should also set `.prototype` on each one
|
//TODO: These need to be constructors and should also set `.prototype` on each one
|
||||||
let object = ScriptObject::function(
|
let object = ScriptObject::function(
|
||||||
|
@ -217,6 +220,12 @@ pub fn create_globals<'gc>(
|
||||||
Some(function_proto),
|
Some(function_proto),
|
||||||
Some(array_proto),
|
Some(array_proto),
|
||||||
);
|
);
|
||||||
|
let xmlnode = ScriptObject::function(
|
||||||
|
gc_context,
|
||||||
|
Executable::Native(xml::xmlnode_constructor),
|
||||||
|
Some(function_proto),
|
||||||
|
Some(xmlnode_proto),
|
||||||
|
);
|
||||||
|
|
||||||
let listeners = SystemListeners::new(gc_context, Some(array_proto));
|
let listeners = SystemListeners::new(gc_context, Some(array_proto));
|
||||||
|
|
||||||
|
@ -228,6 +237,7 @@ pub fn create_globals<'gc>(
|
||||||
globals.define_value(gc_context, "MovieClip", movie_clip.into(), EnumSet::empty());
|
globals.define_value(gc_context, "MovieClip", movie_clip.into(), EnumSet::empty());
|
||||||
globals.define_value(gc_context, "Sound", sound.into(), EnumSet::empty());
|
globals.define_value(gc_context, "Sound", sound.into(), EnumSet::empty());
|
||||||
globals.define_value(gc_context, "TextField", text_field.into(), EnumSet::empty());
|
globals.define_value(gc_context, "TextField", text_field.into(), EnumSet::empty());
|
||||||
|
globals.define_value(gc_context, "XMLNode", xmlnode.into(), EnumSet::empty());
|
||||||
globals.force_set_function(
|
globals.force_set_function(
|
||||||
"Number",
|
"Number",
|
||||||
number,
|
number,
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
//! XML/XMLNode global classes
|
||||||
|
|
||||||
|
use crate::avm1::return_value::ReturnValue;
|
||||||
|
use crate::avm1::script_object::ScriptObject;
|
||||||
|
use crate::avm1::{Avm1, Error, Object, TObject, UpdateContext, Value};
|
||||||
|
use crate::xml::XMLNode;
|
||||||
|
use gc_arena::MutationContext;
|
||||||
|
use std::mem::swap;
|
||||||
|
|
||||||
|
/// XMLNode constructor
|
||||||
|
pub fn xmlnode_constructor<'gc>(
|
||||||
|
avm: &mut Avm1<'gc>,
|
||||||
|
ac: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
|
this: Object<'gc>,
|
||||||
|
args: &[Value<'gc>],
|
||||||
|
) -> Result<ReturnValue<'gc>, Error> {
|
||||||
|
match (
|
||||||
|
args.get(0).map(|v| v.as_number(avm, ac).map(|v| v as u32)),
|
||||||
|
args.get(1).map(|v| v.as_string()),
|
||||||
|
this.as_xml_node(),
|
||||||
|
) {
|
||||||
|
(Some(Ok(1)), Some(Ok(strval)), Some(ref mut this_node)) => {
|
||||||
|
let mut xmlelement = XMLNode::new_text(ac.gc_context, strval);
|
||||||
|
swap(&mut xmlelement, this_node);
|
||||||
|
}
|
||||||
|
(Some(Ok(3)), Some(Ok(strval)), Some(ref mut this_node)) => {
|
||||||
|
let mut xmlelement = XMLNode::new_element(ac.gc_context, strval)?;
|
||||||
|
swap(&mut xmlelement, this_node);
|
||||||
|
}
|
||||||
|
//Invalid nodetype ID, string value missing, or not an XMLElement
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Value::Undefined.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct the prototype for `XMLNode`.
|
||||||
|
pub fn create_xmlnode_proto<'gc>(
|
||||||
|
gc_context: MutationContext<'gc, '_>,
|
||||||
|
proto: Object<'gc>,
|
||||||
|
_fn_proto: Object<'gc>,
|
||||||
|
) -> Object<'gc> {
|
||||||
|
let xmlnode_proto = ScriptObject::object(gc_context, Some(proto));
|
||||||
|
|
||||||
|
xmlnode_proto.into()
|
||||||
|
}
|
|
@ -101,6 +101,7 @@ impl<'gc> TObject<'gc> for XMLObject<'gc> {
|
||||||
self.base().call(avm, context, this, args)
|
self.base().call(avm, context, this, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::new_ret_no_self)]
|
||||||
fn new(
|
fn new(
|
||||||
&self,
|
&self,
|
||||||
_avm: &mut Avm1<'gc>,
|
_avm: &mut Avm1<'gc>,
|
||||||
|
|
|
@ -31,12 +31,20 @@ impl XMLName {
|
||||||
Self::from_bytes_cow(Cow::Borrowed(bytes))
|
Self::from_bytes_cow(Cow::Borrowed(bytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_str(strval: &str) -> Result<Self, Error> {
|
||||||
|
Self::from_str_cow(Cow::Borrowed(strval))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn from_bytes_cow(bytes: Cow<[u8]>) -> Result<Self, Error> {
|
pub fn from_bytes_cow(bytes: Cow<[u8]>) -> Result<Self, Error> {
|
||||||
let full_name = match bytes {
|
let full_name = match bytes {
|
||||||
Cow::Borrowed(ln) => Cow::Borrowed(std::str::from_utf8(ln)?),
|
Cow::Borrowed(ln) => Cow::Borrowed(std::str::from_utf8(ln)?),
|
||||||
Cow::Owned(ln) => Cow::Owned(String::from_utf8(ln)?),
|
Cow::Owned(ln) => Cow::Owned(String::from_utf8(ln)?),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Self::from_str_cow(full_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_str_cow(full_name: Cow<str>) -> Result<Self, Error> {
|
||||||
if let Some(colon_index) = full_name.find(':') {
|
if let Some(colon_index) = full_name.find(':') {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
namespace: Some(full_name[0..colon_index].to_owned()),
|
namespace: Some(full_name[0..colon_index].to_owned()),
|
||||||
|
@ -99,6 +107,18 @@ impl<'gc> XMLNode<'gc> {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construct a new XML element node.
|
||||||
|
pub fn new_element(mc: MutationContext<'gc, '_>, element_name: &str) -> Result<Self, Error> {
|
||||||
|
Ok(XMLNode(GcCell::allocate(
|
||||||
|
mc,
|
||||||
|
XMLNodeData::Element {
|
||||||
|
tag_name: XMLName::from_str(element_name)?,
|
||||||
|
attributes: BTreeMap::new(),
|
||||||
|
children: Vec::new(),
|
||||||
|
},
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
/// Construct an XML node from a `quick_xml` `BytesStart` event.
|
/// Construct an XML node from a `quick_xml` `BytesStart` event.
|
||||||
///
|
///
|
||||||
/// The returned node will always be an `Element`, and it must only contain
|
/// The returned node will always be an `Element`, and it must only contain
|
||||||
|
|
Loading…
Reference in New Issue