Skip to content

Commit acdb0df

Browse files
committed
avm1: Implement TextSnapshot.findText()
1 parent a6bd242 commit acdb0df

File tree

7 files changed

+131
-80
lines changed

7 files changed

+131
-80
lines changed

core/src/avm1/globals/text_snapshot.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,25 @@ fn set_select_color<'gc>(
159159

160160
fn find_text<'gc>(
161161
activation: &mut Activation<'_, 'gc>,
162-
_this: Object<'gc>,
163-
_args: &[Value<'gc>],
162+
this: Object<'gc>,
163+
args: &[Value<'gc>],
164164
) -> Result<Value<'gc>, Error<'gc>> {
165-
avm1_stub!(activation, "TextSnapshot", "findText");
166-
Ok(Value::Undefined)
165+
let NativeObject::TextSnapshot(object) = this.native() else {
166+
return Ok(Value::Undefined);
167+
};
168+
169+
let [start, text, case_sensitive] = args else {
170+
return Ok(Value::Undefined);
171+
};
172+
173+
let start = start.coerce_to_i32(activation)?;
174+
let text = text.coerce_to_string(activation)?;
175+
let case_sensitive = case_sensitive.as_bool(activation.swf_version());
176+
177+
let index = object
178+
.text_snapshot()
179+
.find_text(start, text.as_wstr(), case_sensitive);
180+
Ok(index.into())
167181
}
168182

169183
fn get_text_run_info<'gc>(

core/src/display_object/text.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use gc_arena::{Collect, Gc, Mutation};
1313
use ruffle_common::utils::HasPrefixField;
1414
use ruffle_render::transform::Transform;
1515
use ruffle_wstr::{WStr, WString};
16+
use std::borrow::Cow;
1617
use std::cell::RefCell;
1718
use std::sync::Arc;
1819

@@ -403,4 +404,40 @@ impl<'gc> TextSnapshot<'gc> {
403404

404405
ret
405406
}
407+
408+
pub fn find_text(self, from: i32, text: &WStr, case_sensitive: bool) -> i32 {
409+
if text.is_empty() {
410+
return -1;
411+
}
412+
413+
let Ok(from) = usize::try_from(from) else {
414+
return -1;
415+
};
416+
let count = self.count();
417+
418+
let chunks = self
419+
.0
420+
.chunks
421+
.iter()
422+
.filter(|c| c.global_index + c.text.len() > from)
423+
.map(|c| c.sub_string(from, count));
424+
425+
let mut full_text = WString::new();
426+
for chunk in chunks {
427+
full_text.push_str(chunk);
428+
}
429+
430+
let text = if !case_sensitive {
431+
full_text.make_ascii_lowercase();
432+
Cow::Owned(text.to_ascii_lowercase())
433+
} else {
434+
Cow::Borrowed(text)
435+
};
436+
437+
let Some(index) = full_text.find(text.as_ref()) else {
438+
return -1;
439+
};
440+
441+
i32::try_from(from + index).unwrap_or(-1)
442+
}
406443
}

tests/tests/swfs/from_gnash/actionscript.all/TextSnapshot-v6/output.ruffle.txt

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -59,25 +59,25 @@ PASSED: typeof(ts.findText()) == "undefined" [./TextSnapshot.as:114]
5959
PASSED: typeof(ts.findText("a")) == "undefined" [./TextSnapshot.as:115]
6060
PASSED: typeof(ts.findText(1)) == "undefined" [./TextSnapshot.as:116]
6161
PASSED: typeof(ts.findText(1, "a")) == "undefined" [./TextSnapshot.as:117]
62-
FAILED: expected: "number" obtained: undefined [./TextSnapshot.as:120]
63-
FAILED: expected: "number" obtained: undefined [./TextSnapshot.as:121]
64-
FAILED: expected: "number" obtained: undefined [./TextSnapshot.as:122]
65-
FAILED: expected: "number" obtained: undefined [./TextSnapshot.as:123]
66-
FAILED: expected: "number" obtained: undefined [./TextSnapshot.as:124]
67-
FAILED: expected: "number" obtained: undefined [./TextSnapshot.as:125]
68-
FAILED: expected: "number" obtained: undefined [./TextSnapshot.as:126]
62+
PASSED: typeof(ts.findText(1, "a", true)) == "number" [./TextSnapshot.as:120]
63+
PASSED: typeof(ts.findText(1, "a", 1)) == "number" [./TextSnapshot.as:121]
64+
PASSED: typeof(ts.findText(1, "a", new Date())) == "number" [./TextSnapshot.as:122]
65+
PASSED: typeof(ts.findText("6", "a", new Date())) == "number" [./TextSnapshot.as:123]
66+
PASSED: typeof(ts.findText("b", "a", new Date())) == "number" [./TextSnapshot.as:124]
67+
PASSED: typeof(ts.findText(-1, "a", new Date())) == "number" [./TextSnapshot.as:125]
68+
PASSED: typeof(ts.findText(Infinity, "a", new Date())) == "number" [./TextSnapshot.as:126]
6969
PASSED: typeof(ts.findText(-1, "a", new Date(), "e")) == "undefined" [./TextSnapshot.as:127]
7070
PASSED: typeof(ts.findText(Infinity, "a", new Date(), 3)) == "undefined" [./TextSnapshot.as:128]
71-
FAILED: expected: -1 obtained: [./TextSnapshot.as:130]
72-
FAILED: expected: -1 obtained: [./TextSnapshot.as:131]
73-
FAILED: expected: -1 obtained: [./TextSnapshot.as:132]
74-
FAILED: expected: -1 obtained: [./TextSnapshot.as:133]
75-
FAILED: expected: -1 obtained: [./TextSnapshot.as:134]
76-
FAILED: expected: -1 obtained: [./TextSnapshot.as:135]
77-
FAILED: expected: -1 obtained: [./TextSnapshot.as:136]
71+
PASSED: ts.findText(1, "a", true) == -1 [./TextSnapshot.as:130]
72+
PASSED: ts.findText(1, "a", 1) == -1 [./TextSnapshot.as:131]
73+
PASSED: ts.findText(1, "a", new Date()) == -1 [./TextSnapshot.as:132]
74+
PASSED: ts.findText("6", "a", false) == -1 [./TextSnapshot.as:133]
75+
PASSED: ts.findText("b", "a", true) == -1 [./TextSnapshot.as:134]
76+
PASSED: ts.findText(-1, "a", new Date()) == -1 [./TextSnapshot.as:135]
77+
PASSED: ts.findText(Infinity, "a", new Date()) == -1 [./TextSnapshot.as:136]
7878
PASSED: ts.getCount() == 0 [./TextSnapshot.as:142]
79-
FAILED: expected: -1 obtained: [./TextSnapshot.as:143]
80-
FAILED: expected: -1 obtained: [./TextSnapshot.as:144]
79+
PASSED: ts.findText(1, "a", true) == -1 [./TextSnapshot.as:143]
80+
PASSED: ts.findText(1, "a", false) == -1 [./TextSnapshot.as:144]
8181
PASSED: typeof(ts.getSelected()) == "undefined" [./TextSnapshot.as:148]
8282
PASSED: typeof(ts.getSelected(0)) == "undefined" [./TextSnapshot.as:149]
8383
PASSED: typeof(ts.getSelected("a")) == "undefined" [./TextSnapshot.as:150]
@@ -168,6 +168,6 @@ PASSED: typeof(ts.setSelected(0, 10, true)) == "undefined" [./TextSnapshot.as:24
168168
PASSED: typeof(ts.setSelected(0, 10, "a", 11)) == "undefined" [./TextSnapshot.as:243]
169169
PASSED: typeof(ts.setSelected(0, 10, 10, "hello")) == "undefined" [./TextSnapshot.as:244]
170170
PASSED: typeof(ts.setSelected(0, 10, true, [3, 4])) == "undefined" [./TextSnapshot.as:245]
171-
#passed: 127
172-
#failed: 40
171+
#passed: 143
172+
#failed: 24
173173
#total tests run: 167

tests/tests/swfs/from_gnash/actionscript.all/TextSnapshot-v7/output.ruffle.txt

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -59,25 +59,25 @@ PASSED: typeof(ts.findText()) == "undefined" [./TextSnapshot.as:114]
5959
PASSED: typeof(ts.findText("a")) == "undefined" [./TextSnapshot.as:115]
6060
PASSED: typeof(ts.findText(1)) == "undefined" [./TextSnapshot.as:116]
6161
PASSED: typeof(ts.findText(1, "a")) == "undefined" [./TextSnapshot.as:117]
62-
FAILED: expected: "number" obtained: undefined [./TextSnapshot.as:120]
63-
FAILED: expected: "number" obtained: undefined [./TextSnapshot.as:121]
64-
FAILED: expected: "number" obtained: undefined [./TextSnapshot.as:122]
65-
FAILED: expected: "number" obtained: undefined [./TextSnapshot.as:123]
66-
FAILED: expected: "number" obtained: undefined [./TextSnapshot.as:124]
67-
FAILED: expected: "number" obtained: undefined [./TextSnapshot.as:125]
68-
FAILED: expected: "number" obtained: undefined [./TextSnapshot.as:126]
62+
PASSED: typeof(ts.findText(1, "a", true)) == "number" [./TextSnapshot.as:120]
63+
PASSED: typeof(ts.findText(1, "a", 1)) == "number" [./TextSnapshot.as:121]
64+
PASSED: typeof(ts.findText(1, "a", new Date())) == "number" [./TextSnapshot.as:122]
65+
PASSED: typeof(ts.findText("6", "a", new Date())) == "number" [./TextSnapshot.as:123]
66+
PASSED: typeof(ts.findText("b", "a", new Date())) == "number" [./TextSnapshot.as:124]
67+
PASSED: typeof(ts.findText(-1, "a", new Date())) == "number" [./TextSnapshot.as:125]
68+
PASSED: typeof(ts.findText(Infinity, "a", new Date())) == "number" [./TextSnapshot.as:126]
6969
PASSED: typeof(ts.findText(-1, "a", new Date(), "e")) == "undefined" [./TextSnapshot.as:127]
7070
PASSED: typeof(ts.findText(Infinity, "a", new Date(), 3)) == "undefined" [./TextSnapshot.as:128]
71-
FAILED: expected: -1 obtained: undefined [./TextSnapshot.as:130]
72-
FAILED: expected: -1 obtained: undefined [./TextSnapshot.as:131]
73-
FAILED: expected: -1 obtained: undefined [./TextSnapshot.as:132]
74-
FAILED: expected: -1 obtained: undefined [./TextSnapshot.as:133]
75-
FAILED: expected: -1 obtained: undefined [./TextSnapshot.as:134]
76-
FAILED: expected: -1 obtained: undefined [./TextSnapshot.as:135]
77-
FAILED: expected: -1 obtained: undefined [./TextSnapshot.as:136]
71+
PASSED: ts.findText(1, "a", true) == -1 [./TextSnapshot.as:130]
72+
PASSED: ts.findText(1, "a", 1) == -1 [./TextSnapshot.as:131]
73+
PASSED: ts.findText(1, "a", new Date()) == -1 [./TextSnapshot.as:132]
74+
PASSED: ts.findText("6", "a", false) == -1 [./TextSnapshot.as:133]
75+
PASSED: ts.findText("b", "a", true) == -1 [./TextSnapshot.as:134]
76+
PASSED: ts.findText(-1, "a", new Date()) == -1 [./TextSnapshot.as:135]
77+
PASSED: ts.findText(Infinity, "a", new Date()) == -1 [./TextSnapshot.as:136]
7878
PASSED: ts.getCount() == 0 [./TextSnapshot.as:142]
79-
FAILED: expected: -1 obtained: undefined [./TextSnapshot.as:143]
80-
FAILED: expected: -1 obtained: undefined [./TextSnapshot.as:144]
79+
PASSED: ts.findText(1, "a", true) == -1 [./TextSnapshot.as:143]
80+
PASSED: ts.findText(1, "a", false) == -1 [./TextSnapshot.as:144]
8181
PASSED: typeof(ts.getSelected()) == "undefined" [./TextSnapshot.as:148]
8282
PASSED: typeof(ts.getSelected(0)) == "undefined" [./TextSnapshot.as:149]
8383
PASSED: typeof(ts.getSelected("a")) == "undefined" [./TextSnapshot.as:150]
@@ -168,6 +168,6 @@ PASSED: typeof(ts.setSelected(0, 10, true)) == "undefined" [./TextSnapshot.as:24
168168
PASSED: typeof(ts.setSelected(0, 10, "a", 11)) == "undefined" [./TextSnapshot.as:243]
169169
PASSED: typeof(ts.setSelected(0, 10, 10, "hello")) == "undefined" [./TextSnapshot.as:244]
170170
PASSED: typeof(ts.setSelected(0, 10, true, [3, 4])) == "undefined" [./TextSnapshot.as:245]
171-
#passed: 127
172-
#failed: 40
171+
#passed: 143
172+
#failed: 24
173173
#total tests run: 167

tests/tests/swfs/from_gnash/actionscript.all/TextSnapshot-v8/output.ruffle.txt

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -59,25 +59,25 @@ PASSED: typeof(ts.findText()) == "undefined" [./TextSnapshot.as:114]
5959
PASSED: typeof(ts.findText("a")) == "undefined" [./TextSnapshot.as:115]
6060
PASSED: typeof(ts.findText(1)) == "undefined" [./TextSnapshot.as:116]
6161
PASSED: typeof(ts.findText(1, "a")) == "undefined" [./TextSnapshot.as:117]
62-
FAILED: expected: "number" obtained: undefined [./TextSnapshot.as:120]
63-
FAILED: expected: "number" obtained: undefined [./TextSnapshot.as:121]
64-
FAILED: expected: "number" obtained: undefined [./TextSnapshot.as:122]
65-
FAILED: expected: "number" obtained: undefined [./TextSnapshot.as:123]
66-
FAILED: expected: "number" obtained: undefined [./TextSnapshot.as:124]
67-
FAILED: expected: "number" obtained: undefined [./TextSnapshot.as:125]
68-
FAILED: expected: "number" obtained: undefined [./TextSnapshot.as:126]
62+
PASSED: typeof(ts.findText(1, "a", true)) == "number" [./TextSnapshot.as:120]
63+
PASSED: typeof(ts.findText(1, "a", 1)) == "number" [./TextSnapshot.as:121]
64+
PASSED: typeof(ts.findText(1, "a", new Date())) == "number" [./TextSnapshot.as:122]
65+
PASSED: typeof(ts.findText("6", "a", new Date())) == "number" [./TextSnapshot.as:123]
66+
PASSED: typeof(ts.findText("b", "a", new Date())) == "number" [./TextSnapshot.as:124]
67+
PASSED: typeof(ts.findText(-1, "a", new Date())) == "number" [./TextSnapshot.as:125]
68+
PASSED: typeof(ts.findText(Infinity, "a", new Date())) == "number" [./TextSnapshot.as:126]
6969
PASSED: typeof(ts.findText(-1, "a", new Date(), "e")) == "undefined" [./TextSnapshot.as:127]
7070
PASSED: typeof(ts.findText(Infinity, "a", new Date(), 3)) == "undefined" [./TextSnapshot.as:128]
71-
FAILED: expected: -1 obtained: undefined [./TextSnapshot.as:130]
72-
FAILED: expected: -1 obtained: undefined [./TextSnapshot.as:131]
73-
FAILED: expected: -1 obtained: undefined [./TextSnapshot.as:132]
74-
FAILED: expected: -1 obtained: undefined [./TextSnapshot.as:133]
75-
FAILED: expected: -1 obtained: undefined [./TextSnapshot.as:134]
76-
FAILED: expected: -1 obtained: undefined [./TextSnapshot.as:135]
77-
FAILED: expected: -1 obtained: undefined [./TextSnapshot.as:136]
71+
PASSED: ts.findText(1, "a", true) == -1 [./TextSnapshot.as:130]
72+
PASSED: ts.findText(1, "a", 1) == -1 [./TextSnapshot.as:131]
73+
PASSED: ts.findText(1, "a", new Date()) == -1 [./TextSnapshot.as:132]
74+
PASSED: ts.findText("6", "a", false) == -1 [./TextSnapshot.as:133]
75+
PASSED: ts.findText("b", "a", true) == -1 [./TextSnapshot.as:134]
76+
PASSED: ts.findText(-1, "a", new Date()) == -1 [./TextSnapshot.as:135]
77+
PASSED: ts.findText(Infinity, "a", new Date()) == -1 [./TextSnapshot.as:136]
7878
PASSED: ts.getCount() == 0 [./TextSnapshot.as:142]
79-
FAILED: expected: -1 obtained: undefined [./TextSnapshot.as:143]
80-
FAILED: expected: -1 obtained: undefined [./TextSnapshot.as:144]
79+
PASSED: ts.findText(1, "a", true) == -1 [./TextSnapshot.as:143]
80+
PASSED: ts.findText(1, "a", false) == -1 [./TextSnapshot.as:144]
8181
PASSED: typeof(ts.getSelected()) == "undefined" [./TextSnapshot.as:148]
8282
PASSED: typeof(ts.getSelected(0)) == "undefined" [./TextSnapshot.as:149]
8383
PASSED: typeof(ts.getSelected("a")) == "undefined" [./TextSnapshot.as:150]
@@ -168,6 +168,6 @@ PASSED: typeof(ts.setSelected(0, 10, true)) == "undefined" [./TextSnapshot.as:24
168168
PASSED: typeof(ts.setSelected(0, 10, "a", 11)) == "undefined" [./TextSnapshot.as:243]
169169
PASSED: typeof(ts.setSelected(0, 10, 10, "hello")) == "undefined" [./TextSnapshot.as:244]
170170
PASSED: typeof(ts.setSelected(0, 10, true, [3, 4])) == "undefined" [./TextSnapshot.as:245]
171-
#passed: 127
172-
#failed: 40
171+
#passed: 143
172+
#failed: 24
173173
#total tests run: 167

tests/tests/swfs/from_gnash/misc-ming.all/TextSnapshotTest/output.fp10.ruffle.txt

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ Zweites Textfeld
1313
Some more static text here... abcdefgh' [TextSnapshotTest.c:144]
1414
PASSED: ts.getText(0, 14, true) == 'First text
1515
Zwei' [TextSnapshotTest.c:146]
16-
FAILED: expected: -1 obtained: undefined [TextSnapshotTest.c:148]
17-
FAILED: expected: 0 obtained: undefined [TextSnapshotTest.c:149]
18-
FAILED: expected: 22 obtained: undefined [TextSnapshotTest.c:150]
19-
FAILED: expected: 2 obtained: undefined [TextSnapshotTest.c:151]
20-
FAILED: expected: -1 obtained: undefined [TextSnapshotTest.c:152]
21-
FAILED: expected: -1 obtained: undefined [TextSnapshotTest.c:153]
22-
FAILED: expected: -1 obtained: undefined [TextSnapshotTest.c:154]
23-
FAILED: expected: -1 obtained: undefined [TextSnapshotTest.c:155]
24-
FAILED: expected: -1 obtained: undefined [TextSnapshotTest.c:156]
16+
PASSED: ts.findText(0, '', false) == -1 [TextSnapshotTest.c:148]
17+
PASSED: ts.findText(0, 'f', false) == 0 [TextSnapshotTest.c:149]
18+
PASSED: ts.findText(0, 'f', true) == 22 [TextSnapshotTest.c:150]
19+
PASSED: ts.findText(1, 'Rst', false) == 2 [TextSnapshotTest.c:151]
20+
PASSED: ts.findText(3, 'RSt', false) == -1 [TextSnapshotTest.c:152]
21+
PASSED: ts.findText(100, 'h', false) == -1 [TextSnapshotTest.c:153]
22+
PASSED: ts.findText(64, 'h', false) == -1 [TextSnapshotTest.c:154]
23+
PASSED: ts.findText(-5, 'Zwei', true) == -1 [TextSnapshotTest.c:155]
24+
PASSED: ts.findText(-5, 'gh', true) == -1 [TextSnapshotTest.c:156]
2525
FAILED: expected: ' textZweites TextfeldSome' obtained: undefined [TextSnapshotTest.c:159]
2626
FAILED: expected: ' text
2727
Zweites Textfeld
@@ -127,6 +127,6 @@ PASSED: typeof(ts) == 'undefined' [TextSnapshotTest.c:295]
127127
PASSED: typeof(ts) == 'object' [TextSnapshotTest.c:298]
128128
PASSED: typeof(ts) == 'object' [TextSnapshotTest.c:303]
129129
PASSED: typeof(ts) == 'object' [TextSnapshotTest.c:306]
130-
#passed: 28
131-
#failed: 96
130+
#passed: 37
131+
#failed: 87
132132
#total tests run: 124

tests/tests/swfs/from_gnash/misc-ming.all/TextSnapshotTest/output.fp9.ruffle.txt

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ Zweites Textfeld
1313
Some more static text here... abcdefgh' [TextSnapshotTest.c:144]
1414
PASSED: ts.getText(0, 14, true) == 'First text
1515
Zwei' [TextSnapshotTest.c:146]
16-
FAILED: expected: -1 obtained: undefined [TextSnapshotTest.c:148]
17-
FAILED: expected: 0 obtained: undefined [TextSnapshotTest.c:149]
18-
FAILED: expected: 22 obtained: undefined [TextSnapshotTest.c:150]
19-
FAILED: expected: 2 obtained: undefined [TextSnapshotTest.c:151]
20-
FAILED: expected: -1 obtained: undefined [TextSnapshotTest.c:152]
21-
FAILED: expected: -1 obtained: undefined [TextSnapshotTest.c:153]
22-
FAILED: expected: -1 obtained: undefined [TextSnapshotTest.c:154]
23-
FAILED: expected: -1 obtained: undefined [TextSnapshotTest.c:155]
24-
FAILED: expected: -1 obtained: undefined [TextSnapshotTest.c:156]
16+
PASSED: ts.findText(0, '', false) == -1 [TextSnapshotTest.c:148]
17+
PASSED: ts.findText(0, 'f', false) == 0 [TextSnapshotTest.c:149]
18+
PASSED: ts.findText(0, 'f', true) == 22 [TextSnapshotTest.c:150]
19+
PASSED: ts.findText(1, 'Rst', false) == 2 [TextSnapshotTest.c:151]
20+
PASSED: ts.findText(3, 'RSt', false) == -1 [TextSnapshotTest.c:152]
21+
PASSED: ts.findText(100, 'h', false) == -1 [TextSnapshotTest.c:153]
22+
PASSED: ts.findText(64, 'h', false) == -1 [TextSnapshotTest.c:154]
23+
PASSED: ts.findText(-5, 'Zwei', true) == -1 [TextSnapshotTest.c:155]
24+
PASSED: ts.findText(-5, 'gh', true) == -1 [TextSnapshotTest.c:156]
2525
FAILED: expected: ' textZweites TextfeldSome' obtained: undefined [TextSnapshotTest.c:159]
2626
FAILED: expected: ' text
2727
Zweites Textfeld
@@ -127,6 +127,6 @@ PASSED: typeof(ts) == 'undefined' [TextSnapshotTest.c:295]
127127
PASSED: typeof(ts) == 'object' [TextSnapshotTest.c:298]
128128
PASSED: typeof(ts) == 'object' [TextSnapshotTest.c:303]
129129
PASSED: typeof(ts) == 'object' [TextSnapshotTest.c:306]
130-
#passed: 28
131-
#failed: 96
130+
#passed: 37
131+
#failed: 87
132132
#total tests run: 124

0 commit comments

Comments
 (0)