From f0d356589afaf93314d1dd29af55eaad562547b3 Mon Sep 17 00:00:00 2001 From: Nathan Adams Date: Fri, 18 Aug 2023 00:03:12 +0200 Subject: [PATCH] core: Implement avm2 event: links in texts --- core/src/avm2/object/event_object.rs | 29 ++++++++ core/src/display_object/edit_text.rs | 8 +++ tests/tests/swfs/avm2/textfield_event/Test.as | 47 ++++++++++++ .../swfs/avm2/textfield_event/input.json | 42 +++++++++++ .../swfs/avm2/textfield_event/output.txt | 68 ++++++++++++++++++ .../tests/swfs/avm2/textfield_event/test.fla | Bin 0 -> 5740 bytes .../tests/swfs/avm2/textfield_event/test.swf | Bin 0 -> 19305 bytes .../tests/swfs/avm2/textfield_event/test.toml | 1 + 8 files changed, 195 insertions(+) create mode 100644 tests/tests/swfs/avm2/textfield_event/Test.as create mode 100644 tests/tests/swfs/avm2/textfield_event/input.json create mode 100644 tests/tests/swfs/avm2/textfield_event/output.txt create mode 100644 tests/tests/swfs/avm2/textfield_event/test.fla create mode 100644 tests/tests/swfs/avm2/textfield_event/test.swf create mode 100644 tests/tests/swfs/avm2/textfield_event/test.toml diff --git a/core/src/avm2/object/event_object.rs b/core/src/avm2/object/event_object.rs index 417ce9c91..3364f1a01 100644 --- a/core/src/avm2/object/event_object.rs +++ b/core/src/avm2/object/event_object.rs @@ -145,6 +145,35 @@ impl<'gc> EventObject<'gc> { .unwrap() // we don't expect to break here } + pub fn text_event( + activation: &mut Activation<'_, 'gc>, + event_type: S, + text: AvmString<'gc>, + bubbles: bool, + cancelable: bool, + ) -> Object<'gc> + where + S: Into>, + { + let event_type: AvmString<'gc> = event_type.into(); + + let text_event_cls = activation.avm2().classes().textevent; + text_event_cls + .construct( + activation, + &[ + event_type.into(), + // bubbles + bubbles.into(), + // cancelable + cancelable.into(), + // text + text.into(), + ], + ) + .unwrap() // we don't expect to break here + } + pub fn net_status_event( activation: &mut Activation<'_, 'gc>, event_type: S, diff --git a/core/src/display_object/edit_text.rs b/core/src/display_object/edit_text.rs index ddff1bb4d..7fe35b330 100644 --- a/core/src/display_object/edit_text.rs +++ b/core/src/display_object/edit_text.rs @@ -1637,6 +1637,14 @@ impl<'gc> EditText<'gc> { if let Err(e) = self.execute_avm1_asfunction(context, address) { error!("Couldn't execute URL \"{url:?}\": {e:?}"); } + } else if let Some(address) = url.strip_prefix(WStr::from_units(b"event:")) { + if let Avm2Value::Object(object) = self.object2() { + let mut activation = Avm2Activation::from_nothing(context.reborrow()); + let text = AvmString::new(activation.context.gc_context, address); + let event = Avm2EventObject::text_event(&mut activation, "link", text, true, false); + + Avm2::dispatch_event(&mut activation.context, event, object); + } } else { context .navigator diff --git a/tests/tests/swfs/avm2/textfield_event/Test.as b/tests/tests/swfs/avm2/textfield_event/Test.as new file mode 100644 index 000000000..a5e018040 --- /dev/null +++ b/tests/tests/swfs/avm2/textfield_event/Test.as @@ -0,0 +1,47 @@ +package { + + import flash.display.MovieClip; + import flash.text.TextField; + import flash.events.TextEvent; + + + public class Test extends MovieClip { + public var text: TextField; + + public function Test() { + text.htmlText = "" + + "

Click here to call alert 1

" + + "

Or click here to call alert 2

" + + "

this one is empty

" + + "

But this one has lots of args!

" + + ""; + text.addEventListener(TextEvent.LINK, this.onLink); + } + + function onLink(event: TextEvent) { + trace("/// onLink called!"); + trace("// event.text"); + trace(event.text); + trace(""); + + trace("// event.bubbles"); + trace(event.bubbles); + trace(""); + + trace("// event.cancelable"); + trace(event.cancelable); + trace(""); + + trace("// event.currentTarget"); + trace(event.currentTarget); + trace(""); + + trace("// event.target"); + trace(event.target); + trace(""); + + trace(""); + } + } + +} diff --git a/tests/tests/swfs/avm2/textfield_event/input.json b/tests/tests/swfs/avm2/textfield_event/input.json new file mode 100644 index 000000000..81681fc0d --- /dev/null +++ b/tests/tests/swfs/avm2/textfield_event/input.json @@ -0,0 +1,42 @@ +[ + { + "type": "MouseDown", + "pos": [134, 69], + "btn": "Left" + }, + { + "type": "MouseUp", + "pos": [134, 69], + "btn": "Left" + }, + { + "type": "MouseDown", + "pos": [166, 95], + "btn": "Left" + }, + { + "type": "MouseUp", + "pos": [166, 95], + "btn": "Left" + }, + { + "type": "MouseDown", + "pos": [143, 128], + "btn": "Left" + }, + { + "type": "MouseUp", + "pos": [143, 128], + "btn": "Left" + }, + { + "type": "MouseDown", + "pos": [142, 160], + "btn": "Left" + }, + { + "type": "MouseUp", + "pos": [142, 160], + "btn": "Left" + } +] \ No newline at end of file diff --git a/tests/tests/swfs/avm2/textfield_event/output.txt b/tests/tests/swfs/avm2/textfield_event/output.txt new file mode 100644 index 000000000..67997dea0 --- /dev/null +++ b/tests/tests/swfs/avm2/textfield_event/output.txt @@ -0,0 +1,68 @@ +/// onLink called! +// event.text +alert1 + +// event.bubbles +true + +// event.cancelable +false + +// event.currentTarget +[object TextField] + +// event.target +[object TextField] + + +/// onLink called! +// event.text +Second Test + +// event.bubbles +true + +// event.cancelable +false + +// event.currentTarget +[object TextField] + +// event.target +[object TextField] + + +/// onLink called! +// event.text + + +// event.bubbles +true + +// event.cancelable +false + +// event.currentTarget +[object TextField] + +// event.target +[object TextField] + + +/// onLink called! +// event.text +a,b,c,d + +// event.bubbles +true + +// event.cancelable +false + +// event.currentTarget +[object TextField] + +// event.target +[object TextField] + + diff --git a/tests/tests/swfs/avm2/textfield_event/test.fla b/tests/tests/swfs/avm2/textfield_event/test.fla new file mode 100644 index 0000000000000000000000000000000000000000..7095be6fccc380720701e6ef247da524771d03a6 GIT binary patch literal 5740 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 literal 0 HcmV?d00001 diff --git a/tests/tests/swfs/avm2/textfield_event/test.swf b/tests/tests/swfs/avm2/textfield_event/test.swf new file mode 100644 index 0000000000000000000000000000000000000000..3bc0ea4e8a2ffb0c902a094a00f9413f43142529 GIT binary patch literal 19305 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 u*Zh|2w_ShL_19d#