Add trim/trimStart/trimEnd to string prototype
@@ -77,6 +77,42 @@ pub fn char_code_at(this: Value, _: Value, args: Vec<Value>) -> ResultValue {
Ok(to_value(utf16_val as f64))
}
+fn is_trimmable_whitespace(c: char) -> bool {
+ // The rust implementation of `trim` does not regard the same characters whitespace as ecma standard does
+ //
+ // Rust uses \p{White_Space} by default, which also includes:
+ // `\u{0085}' (next line)
+ // And does not include:
+ // '\u{FEFF}' (zero width non-breaking space)
+ match c {
+ // Explicit whitespace: https://tc39.es/ecma262/#sec-white-space
+ '\u{0009}' | '\u{000B}' | '\u{000C}' | '\u{0020}' | '\u{00A0}' | '\u{FEFF}' => true,
+ // Unicode Space_Seperator category
+ '\u{1680}' | '\u{2000}'..='\u{200A}' | '\u{202F}' | '\u{205F}' | '\u{3000}' => true,
+ // Line terminators: https://tc39.es/ecma262/#sec-line-terminators
+ '\u{000A}' | '\u{000D}' | '\u{2028}' | '\u{2029}' => true,
+ _ => false,
+ }
+}
+
+pub fn trim(this: Value, _: Value, _: Vec<Value>) -> ResultValue {
+ let this_str: String =
+ from_value(this.get_private_field(String::from("PrimitiveValue"))).unwrap();
+ Ok(to_value(this_str.trim_matches(is_trimmable_whitespace)))
+}
+
+pub fn trim_start(this: Value, _: Value, _: Vec<Value>) -> ResultValue {
+ let this_str: String =
+ from_value(this.get_private_field(String::from("PrimitiveValue"))).unwrap();
+ Ok(to_value(this_str.trim_start_matches(is_trimmable_whitespace)))
+}
+
+pub fn trim_end(this: Value, _: Value, _: Vec<Value>) -> ResultValue {
+ let this_str: String =
+ from_value(this.get_private_field(String::from("PrimitiveValue"))).unwrap();
+ Ok(to_value(this_str.trim_end_matches(is_trimmable_whitespace)))
+}
+
/// Create a new `String` object
pub fn _create(global: &Value) -> Value {
let string = to_value(make_string as NativeFunctionData);
@@ -93,6 +129,9 @@ pub fn _create(global: &Value) -> Value {
proto.set_field_slice("charAt", to_value(char_at as NativeFunctionData));
proto.set_field_slice("charCodeAt", to_value(char_code_at as NativeFunctionData));
proto.set_field_slice("toString", to_value(to_string as NativeFunctionData));
+ proto.set_field_slice("trim", to_value(trim as NativeFunctionData));
+ proto.set_field_slice("trimStart", to_value(trim_start as NativeFunctionData));
+ proto.set_field_slice("trimEnd", to_value(trim_end as NativeFunctionData));
string.set_field_slice(PROTOTYPE, proto);
string
}
