From a61d2b54ae9558741cf7455edf495ed1b42d95d1 Mon Sep 17 00:00:00 2001 From: Mike Welsh Date: Sat, 21 Nov 2020 15:13:27 -0800 Subject: [PATCH] avm1: Implement TextField.type --- core/src/avm1/globals/text_field.rs | 91 ++++++++++++++++++ core/src/display_object/edit_text.rs | 8 ++ core/tests/regression_tests.rs | 1 + .../swfs/avm1/textfield_properties/output.txt | 8 ++ .../swfs/avm1/textfield_properties/test.fla | Bin 0 -> 4762 bytes .../swfs/avm1/textfield_properties/test.swf | Bin 0 -> 3717 bytes 6 files changed, 108 insertions(+) create mode 100644 core/tests/swfs/avm1/textfield_properties/output.txt create mode 100644 core/tests/swfs/avm1/textfield_properties/test.fla create mode 100644 core/tests/swfs/avm1/textfield_properties/test.swf diff --git a/core/src/avm1/globals/text_field.rs b/core/src/avm1/globals/text_field.rs index b303b8644..ce09c2ceb 100644 --- a/core/src/avm1/globals/text_field.rs +++ b/core/src/avm1/globals/text_field.rs @@ -208,6 +208,64 @@ macro_rules! with_text_field { }}; } +macro_rules! with_text_field_props { + ($obj:ident, $gc:ident, $fn_proto:ident, $($name:literal => [$get:ident $(, $set:ident)*],)*) => { + $( + $obj.add_property( + $gc, + $name, + with_text_field_props!(getter $gc, $fn_proto, $get), + with_text_field_props!(setter $gc, $fn_proto, $($set),*), + Default::default() + ); + )* + }; + + (getter $gc:ident, $fn_proto:ident, $get:ident) => { + FunctionObject::function( + $gc, + Executable::Native( + |activation: &mut Activation<'_, 'gc, '_>, this, _args| -> Result, Error<'gc>> { + if let Some(display_object) = this.as_display_object() { + if let Some(edit_text) = display_object.as_edit_text() { + return $get(edit_text, activation); + } + } + Ok(Value::Undefined) + } as crate::avm1::function::NativeFunction<'gc> + ), + Some($fn_proto), + $fn_proto + ) + }; + + (setter $gc:ident, $fn_proto:ident, $set:ident) => { + Some(FunctionObject::function( + $gc, + Executable::Native( + |activation: &mut Activation<'_, 'gc, '_>, this, args| -> Result, Error<'gc>> { + if let Some(display_object) = this.as_display_object() { + if let Some(edit_text) = display_object.as_edit_text() { + let value = args + .get(0) + .unwrap_or(&Value::Undefined) + .clone(); + $set(edit_text, activation, value)?; + } + } + Ok(Value::Undefined) + } as crate::avm1::function::NativeFunction<'gc> + ), + Some($fn_proto), + $fn_proto) + ) + }; + + (setter $gc:ident, $fn_proto:ident,) => { + None + }; +} + pub fn text_width<'gc>( activation: &mut Activation<'_, 'gc, '_>, this: Object<'gc>, @@ -452,6 +510,11 @@ pub fn create_proto<'gc>( "replaceText" => replace_text ); + with_text_field_props!( + object, gc_context, fn_proto, + "type" => [get_type, set_type], + ); + object.into() } @@ -770,3 +833,31 @@ fn replace_text<'gc>( Ok(Value::Undefined) } + +pub fn get_type<'gc>( + this: EditText<'gc>, + activation: &mut Activation<'_, 'gc, '_>, +) -> Result, Error<'gc>> { + let tf_type = match this.is_editable() { + true => "input", + false => "dynamic", + }; + Ok(AvmString::new(activation.context.gc_context, tf_type).into()) +} + +pub fn set_type<'gc>( + this: EditText<'gc>, + activation: &mut Activation<'_, 'gc, '_>, + value: Value<'gc>, +) -> Result<(), Error<'gc>> { + match value + .coerce_to_string(activation)? + .to_ascii_lowercase() + .as_str() + { + "input" => this.set_editable(true, &mut activation.context), + "dynamic" => this.set_editable(false, &mut activation.context), + value => log::warn!("Invalid TextField.type: {}", value), + }; + Ok(()) +} diff --git a/core/src/display_object/edit_text.rs b/core/src/display_object/edit_text.rs index c81580051..3a0804b73 100644 --- a/core/src/display_object/edit_text.rs +++ b/core/src/display_object/edit_text.rs @@ -411,6 +411,14 @@ impl<'gc> EditText<'gc> { self.relayout(context); } + pub fn is_editable(self) -> bool { + self.0.read().is_editable + } + + pub fn set_editable(self, is_editable: bool, context: &mut UpdateContext<'_, 'gc, '_>) { + self.0.write(context.gc_context).is_editable = is_editable; + } + pub fn is_multiline(self) -> bool { self.0.read().is_multiline } diff --git a/core/tests/regression_tests.rs b/core/tests/regression_tests.rs index cf7c7d479..68ec71d8f 100644 --- a/core/tests/regression_tests.rs +++ b/core/tests/regression_tests.rs @@ -245,6 +245,7 @@ swf_tests! { #[ignore] (edittext_html_roundtrip, "avm1/edittext_html_roundtrip", 1), (edittext_newline_stripping, "avm1/edittext_newline_stripping", 1), (define_local, "avm1/define_local", 1), + (textfield_properties, "avm1/textfield_properties", 1), (textfield_variable, "avm1/textfield_variable", 8), (error, "avm1/error", 1), (color_transform, "avm1/color_transform", 1), diff --git a/core/tests/swfs/avm1/textfield_properties/output.txt b/core/tests/swfs/avm1/textfield_properties/output.txt new file mode 100644 index 000000000..bdd1e2c9d --- /dev/null +++ b/core/tests/swfs/avm1/textfield_properties/output.txt @@ -0,0 +1,8 @@ +// txt.type: +dynamic +// txt.type = 'input': +input +// txt.type = 'DYNAMIC': +dynamic +// txt.type = 'invalid': +dynamic diff --git a/core/tests/swfs/avm1/textfield_properties/test.fla b/core/tests/swfs/avm1/textfield_properties/test.fla new file mode 100644 index 0000000000000000000000000000000000000000..0ddcc4fdf518cace1d003a5ecf796657813629c1 GIT binary patch literal 4762 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 T_j4i}odG}ye!fmb~<( literal 0 HcmV?d00001 diff --git a/core/tests/swfs/avm1/textfield_properties/test.swf b/core/tests/swfs/avm1/textfield_properties/test.swf new file mode 100644 index 0000000000000000000000000000000000000000..cf6aa7e3f7a36b16e6559b8a182645ba9c9e3061 GIT binary patch literal 3717 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