|
|
@ -77,6 +77,42 @@ pub fn char_code_at(this: Value, _: Value, args: Vec<Value>) -> ResultValue { |
|
|
|
Ok(to_value(utf16_val as f64)) |
|
|
|
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
|
|
|
|
/// Create a new `String` object
|
|
|
|
pub fn _create(global: &Value) -> Value { |
|
|
|
pub fn _create(global: &Value) -> Value { |
|
|
|
let string = to_value(make_string as NativeFunctionData); |
|
|
|
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("charAt", to_value(char_at as NativeFunctionData)); |
|
|
|
proto.set_field_slice("charCodeAt", to_value(char_code_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("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.set_field_slice(PROTOTYPE, proto); |
|
|
|
string |
|
|
|
string |
|
|
|
} |
|
|
|
} |
|
|
|