LibJS: Add String.prototype.pad{Start,End}()

This commit is contained in:
Linus Groh 2020-04-10 15:22:58 +01:00 committed by Andreas Kling
parent 7636dee2cb
commit 31505dde7e
Notes: sideshowbarker 2024-07-19 07:44:21 +09:00
5 changed files with 107 additions and 23 deletions

View file

@ -1,29 +1,14 @@
var now = Date.now();
console.log("Unix timestamp: " + now / 1000);
// FIXME: We need String.prototype.padStart() :^)
var d = new Date();
var year = d.getFullYear();
var month = d.getMonth() + 1;
if (month < 10)
month = "0" + month;
var day = d.getDate();
if (day < 10)
day = "0" + day;
var hours = d.getHours();
if (hours < 10)
hours = "0" + hours;
var minutes = d.getMinutes();
if (minutes < 10)
minutes = "0" + minutes;
var seconds = d.getSeconds();
if (seconds < 10)
seconds = "0" + seconds;
var milliseconds = d.getMilliseconds();
if (milliseconds < 10) {
milliseconds = "00" + milliseconds;
} else if (milliseconds < 100) {
milliseconds = "0" + milliseconds;
}
var month = (d.getMonth() + 1).toString().padStart(2, "0");
var day = d.getDate().toString().padStart(2, "0");
var hours = d.getHours().toString().padStart(2, "0");
var minutes = d.getMinutes().toString().padStart(2, "0");
var seconds = d.getSeconds().toString().padStart(2, "0");
var milliseconds = d.getMilliseconds().toString().padStart(3, "0");
console.log("Date: " + year + "-" + month + "-" + day);
console.log("Time: " + hours + ":" + minutes + ":" + seconds + "." + milliseconds);

View file

@ -49,6 +49,8 @@ StringPrototype::StringPrototype()
put_native_function("toLowerCase", to_lowercase, 0);
put_native_function("toUpperCase", to_uppercase, 0);
put_native_function("toString", to_string, 0);
put_native_function("padStart", pad_start, 1);
put_native_function("padEnd", pad_end, 1);
}
StringPrototype::~StringPrototype()
@ -171,7 +173,7 @@ Value StringPrototype::length_getter(Interpreter& interpreter)
auto* string_object = string_object_from(interpreter);
if (!string_object)
return {};
return Value((i32) string_object->primitive_string()->string().length());
return Value((i32)string_object->primitive_string()->string().length());
}
Value StringPrototype::to_string(Interpreter& interpreter)
@ -182,4 +184,55 @@ Value StringPrototype::to_string(Interpreter& interpreter)
return js_string(interpreter, string_object->primitive_string()->string());
}
enum class PadPlacement {
Start,
End,
};
static Value pad_string(Interpreter& interpreter, Object* object, PadPlacement placement)
{
auto string = object->to_string().as_string()->string();
if (interpreter.argument(0).to_number().is_nan()
|| interpreter.argument(0).to_number().is_undefined()
|| interpreter.argument(0).to_number().to_i32() < 0) {
return js_string(interpreter, string);
}
auto max_length = static_cast<size_t>(interpreter.argument(0).to_i32());
if (max_length <= string.length())
return js_string(interpreter, string);
String fill_string = " ";
if (!interpreter.argument(1).is_undefined())
fill_string = interpreter.argument(1).to_string();
if (fill_string.is_empty())
return js_string(interpreter, string);
auto fill_length = max_length - string.length();
StringBuilder filler_builder;
while (filler_builder.length() < fill_length)
filler_builder.append(fill_string);
auto filler = filler_builder.build().substring(0, fill_length);
if (placement == PadPlacement::Start)
return js_string(interpreter, String::format("%s%s", filler.characters(), string.characters()));
return js_string(interpreter, String::format("%s%s", string.characters(), filler.characters()));
}
Value StringPrototype::pad_start(Interpreter& interpreter)
{
auto* this_object = interpreter.this_value().to_object(interpreter.heap());
if (!this_object)
return {};
return pad_string(interpreter, this_object, PadPlacement::Start);
}
Value StringPrototype::pad_end(Interpreter& interpreter)
{
auto* this_object = interpreter.this_value().to_object(interpreter.heap());
if (!this_object)
return {};
return pad_string(interpreter, this_object, PadPlacement::End);
}
}

View file

@ -45,6 +45,8 @@ private:
static Value to_lowercase(Interpreter&);
static Value to_uppercase(Interpreter&);
static Value to_string(Interpreter&);
static Value pad_start(Interpreter&);
static Value pad_end(Interpreter&);
static Value length_getter(Interpreter&);
};

View file

@ -0,0 +1,22 @@
try {
assert(String.prototype.padEnd.length === 1);
var s = "foo";
assert(s.padEnd(-1) === "foo");
assert(s.padEnd(0) === "foo");
assert(s.padEnd(3) === "foo");
assert(s.padEnd(5) === "foo ");
assert(s.padEnd(10) === "foo ");
assert(s.padEnd("5") === "foo ");
assert(s.padEnd([[["5"]]]) === "foo ");
assert(s.padEnd(2, "+") === "foo");
assert(s.padEnd(5, "+") === "foo++");
assert(s.padEnd(5, 1) === "foo11");
assert(s.padEnd(10, null) === "foonullnul");
assert(s.padEnd(10, "bar") === "foobarbarb");
assert(s.padEnd(10, "123456789") === "foo1234567");
console.log("PASS");
} catch (e) {
console.log("FAIL: " + e);
}

View file

@ -0,0 +1,22 @@
try {
assert(String.prototype.padStart.length === 1);
var s = "foo";
assert(s.padStart(-1) === "foo");
assert(s.padStart(0) === "foo");
assert(s.padStart(3) === "foo");
assert(s.padStart(5) === " foo");
assert(s.padStart(10) === " foo");
assert(s.padStart("5") === " foo");
assert(s.padStart([[["5"]]]) === " foo");
assert(s.padStart(2, "+") === "foo");
assert(s.padStart(5, "+") === "++foo");
assert(s.padStart(5, 1) === "11foo");
assert(s.padStart(10, null) === "nullnulfoo");
assert(s.padStart(10, "bar") === "barbarbfoo");
assert(s.padStart(10, "123456789") === "1234567foo");
console.log("PASS");
} catch (e) {
console.log("FAIL: " + e);
}