fix(script): implement ExtendScript String.substr compatibility (#840)

This commit is contained in:
Nigel Ihza Firdausy 2026-10-11 21:41:21 +07:00
parent 9a7d3e7699
commit 3cdc7af9ff
2 changed files with 41 additions and 0 deletions

View File

@ -27,6 +27,25 @@ function __str(v) {
return String(v);
}
// ExtendScript includes the ES3 String.substr(start, length) method, which Boa
// does not currently provide. Follow its legacy length (not end-index) semantics.
if (typeof String.prototype.substr !== "function") {
Object.defineProperty(String.prototype, "substr", {
value: function (start, length) {
if (this === null || this === undefined) throw new TypeError("String.substr called on null or undefined");
var text = String(this), n = text.length;
var from = Number(start);
if (isNaN(from)) from = 0;
// ToIntegerOrInfinity, then clamp positive or negative offsets.
from = from < 0 ? Math.max(n + Math.ceil(from), 0) : Math.min(Math.floor(from), n);
var count = length === undefined ? n - from : Number(length);
if (isNaN(count) || count <= 0) return "";
return text.slice(from, from + count);
},
writable: true, configurable: true
});
}
// ------------------------------------------------------------------ enums
function __enum(name, keys, base) {

View File

@ -730,3 +730,25 @@ fn import_options_sequence_picks_one_still_or_the_run() {
assert_eq!(kind_of(&s, "shot_[0001-0003].png"), FootageKind::Sequence);
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
fn extendscript_substr_keeps_start_and_length_semantics() {
let mut s = session();
let o = ok(
&mut s,
r#"[
"abcdef".substr(0, 2),
"abcdef".substr(2, 3),
"abcdef".substr(-2),
"abcdef".substr(-20, 2),
"abcdef".substr(2, 0),
"abcdef".substr(2, -3),
"abcdef".substr(2.9, 2.9),
"abcdef".substr(3),
"abcdef".substr(30, 2),
"abcdef".substr(NaN, 2),
"abcdef".substr(2, NaN)
]"#,
);
assert_eq!(o.result, json!(["ab", "cde", "ef", "ab", "", "", "cd", "def", "", "ab", ""]));
}