Procházet zdrojové kódy

LibJS: Add Date methods: setHours, setMinutes, setSeconds, setMilliseconds

tuqqu před 4 roky
rodič
revize
43f0c92bcd

+ 4 - 0
Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h

@@ -201,7 +201,11 @@ namespace JS {
     P(round)                                 \
     P(round)                                 \
     P(set)                                   \
     P(set)                                   \
     P(setFullYear)                           \
     P(setFullYear)                           \
+    P(setHours)                              \
+    P(setMilliseconds)                       \
+    P(setMinutes)                            \
     P(setPrototypeOf)                        \
     P(setPrototypeOf)                        \
+    P(setSeconds)                            \
     P(shift)                                 \
     P(shift)                                 \
     P(sign)                                  \
     P(sign)                                  \
     P(sin)                                   \
     P(sin)                                   \

+ 5 - 0
Userland/Libraries/LibJS/Runtime/Date.h

@@ -63,6 +63,11 @@ public:
     int utc_month() const;
     int utc_month() const;
     int utc_seconds() const;
     int utc_seconds() const;
 
 
+    void set_milliseconds(u16 milliseconds)
+    {
+        m_milliseconds = milliseconds;
+    }
+
     String date_string() const { return m_datetime.to_string("%a %b %d %Y"); }
     String date_string() const { return m_datetime.to_string("%a %b %d %Y"); }
     // FIXME: Deal with timezones once SerenityOS has a working tzset(3)
     // FIXME: Deal with timezones once SerenityOS has a working tzset(3)
     String time_string() const { return m_datetime.to_string("%T GMT+0000 (UTC)"); }
     String time_string() const { return m_datetime.to_string("%T GMT+0000 (UTC)"); }

+ 125 - 1
Userland/Libraries/LibJS/Runtime/DatePrototype.cpp

@@ -62,10 +62,14 @@ void DatePrototype::initialize(GlobalObject& global_object)
     define_native_function(vm.names.getFullYear, get_full_year, 0, attr);
     define_native_function(vm.names.getFullYear, get_full_year, 0, attr);
     define_native_function(vm.names.setFullYear, set_full_year, 3, attr);
     define_native_function(vm.names.setFullYear, set_full_year, 3, attr);
     define_native_function(vm.names.getHours, get_hours, 0, attr);
     define_native_function(vm.names.getHours, get_hours, 0, attr);
+    define_native_function(vm.names.setHours, set_hours, 4, attr);
     define_native_function(vm.names.getMilliseconds, get_milliseconds, 0, attr);
     define_native_function(vm.names.getMilliseconds, get_milliseconds, 0, attr);
+    define_native_function(vm.names.setMilliseconds, set_milliseconds, 1, attr);
     define_native_function(vm.names.getMinutes, get_minutes, 0, attr);
     define_native_function(vm.names.getMinutes, get_minutes, 0, attr);
+    define_native_function(vm.names.setMinutes, set_minutes, 3, attr);
     define_native_function(vm.names.getMonth, get_month, 0, attr);
     define_native_function(vm.names.getMonth, get_month, 0, attr);
     define_native_function(vm.names.getSeconds, get_seconds, 0, attr);
     define_native_function(vm.names.getSeconds, get_seconds, 0, attr);
+    define_native_function(vm.names.setSeconds, set_seconds, 2, attr);
     define_native_function(vm.names.getTime, get_time, 0, attr);
     define_native_function(vm.names.getTime, get_time, 0, attr);
     define_native_function(vm.names.getUTCDate, get_utc_date, 0, attr);
     define_native_function(vm.names.getUTCDate, get_utc_date, 0, attr);
     define_native_function(vm.names.getUTCDay, get_utc_day, 0, attr);
     define_native_function(vm.names.getUTCDay, get_utc_day, 0, attr);
@@ -150,7 +154,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_full_year)
     }
     }
 
 
     datetime.set_time(new_year, new_month, new_day, datetime.hour(), datetime.minute(), datetime.second());
     datetime.set_time(new_year, new_month, new_day, datetime.hour(), datetime.minute(), datetime.second());
-    return Value { this_object->time() };
+    return Value(this_object->time());
 }
 }
 
 
 JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_hours)
 JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_hours)
@@ -161,6 +165,48 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_hours)
     return Value(static_cast<double>(this_object->hours()));
     return Value(static_cast<double>(this_object->hours()));
 }
 }
 
 
+JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_hours)
+{
+    auto* this_object = typed_this(vm, global_object);
+    if (!this_object)
+        return {};
+
+    auto new_hours = vm.argument(0).to_i32(global_object);
+    if (vm.exception())
+        return {};
+
+    auto& datetime = this_object->datetime();
+
+    i32 new_minutes;
+    if (vm.argument_count() >= 2) {
+        new_minutes = vm.argument(1).to_i32(global_object);
+        if (vm.exception())
+            return {};
+    } else {
+        new_minutes = datetime.minute();
+    }
+
+    i32 new_seconds;
+    if (vm.argument_count() >= 3) {
+        new_seconds = vm.argument(2).to_i32(global_object);
+        if (vm.exception())
+            return {};
+    } else {
+        new_seconds = datetime.second();
+    }
+
+    if (vm.argument_count() >= 4) {
+        auto new_milliseconds = vm.argument(3).to_i32(global_object);
+        if (vm.exception())
+            return {};
+        new_seconds += new_milliseconds / 1000;
+        this_object->set_milliseconds(new_milliseconds % 1000);
+    }
+
+    datetime.set_time(datetime.year(), datetime.month(), datetime.day(), new_hours, new_minutes, new_seconds);
+    return Value(this_object->time());
+}
+
 JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_milliseconds)
 JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_milliseconds)
 {
 {
     auto* this_object = typed_this(vm, global_object);
     auto* this_object = typed_this(vm, global_object);
@@ -169,6 +215,27 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_milliseconds)
     return Value(static_cast<double>(this_object->milliseconds()));
     return Value(static_cast<double>(this_object->milliseconds()));
 }
 }
 
 
+JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_milliseconds)
+{
+    auto* this_object = typed_this(vm, global_object);
+    if (!this_object)
+        return {};
+
+    auto new_milliseconds = vm.argument(0).to_i32(global_object);
+    if (vm.exception())
+        return {};
+
+    this_object->set_milliseconds(new_milliseconds % 1000);
+
+    auto added_seconds = new_milliseconds / 1000;
+    if (added_seconds > 0) {
+        auto& datetime = this_object->datetime();
+        datetime.set_time(datetime.year(), datetime.month(), datetime.day(), datetime.hour(), datetime.minute(), datetime.second() + added_seconds);
+    }
+
+    return Value(this_object->time());
+}
+
 JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_minutes)
 JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_minutes)
 {
 {
     auto* this_object = typed_this(vm, global_object);
     auto* this_object = typed_this(vm, global_object);
@@ -177,6 +244,39 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_minutes)
     return Value(static_cast<double>(this_object->minutes()));
     return Value(static_cast<double>(this_object->minutes()));
 }
 }
 
 
+JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_minutes)
+{
+    auto* this_object = typed_this(vm, global_object);
+    if (!this_object)
+        return {};
+
+    auto new_minutes = vm.argument(0).to_i32(global_object);
+    if (vm.exception())
+        return {};
+
+    auto& datetime = this_object->datetime();
+
+    i32 new_seconds;
+    if (vm.argument_count() >= 2) {
+        new_seconds = vm.argument(1).to_i32(global_object);
+        if (vm.exception())
+            return {};
+    } else {
+        new_seconds = datetime.second();
+    }
+
+    if (vm.argument_count() >= 3) {
+        auto new_milliseconds = vm.argument(2).to_i32(global_object);
+        if (vm.exception())
+            return {};
+        new_seconds += new_milliseconds / 1000;
+        this_object->set_milliseconds(new_milliseconds % 1000);
+    }
+
+    datetime.set_time(datetime.year(), datetime.month(), datetime.day(), datetime.hour(), new_minutes, new_seconds);
+    return Value(this_object->time());
+}
+
 JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_month)
 JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_month)
 {
 {
     auto* this_object = typed_this(vm, global_object);
     auto* this_object = typed_this(vm, global_object);
@@ -193,6 +293,30 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_seconds)
     return Value(static_cast<double>(this_object->seconds()));
     return Value(static_cast<double>(this_object->seconds()));
 }
 }
 
 
+JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_seconds)
+{
+    auto* this_object = typed_this(vm, global_object);
+    if (!this_object)
+        return {};
+
+    auto new_seconds = vm.argument(0).to_i32(global_object);
+    if (vm.exception())
+        return {};
+
+    if (vm.argument_count() >= 2) {
+        auto new_milliseconds = vm.argument(1).to_i32(global_object);
+        if (vm.exception())
+            return {};
+        new_seconds += new_milliseconds / 1000;
+        this_object->set_milliseconds(new_milliseconds % 1000);
+    }
+
+    auto& datetime = this_object->datetime();
+
+    datetime.set_time(datetime.year(), datetime.month(), datetime.day(), datetime.hour(), datetime.minute(), new_seconds);
+    return Value(this_object->time());
+}
+
 JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_time)
 JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_time)
 {
 {
     auto* this_object = typed_this(vm, global_object);
     auto* this_object = typed_this(vm, global_object);

+ 4 - 0
Userland/Libraries/LibJS/Runtime/DatePrototype.h

@@ -44,10 +44,14 @@ private:
     JS_DECLARE_NATIVE_FUNCTION(get_full_year);
     JS_DECLARE_NATIVE_FUNCTION(get_full_year);
     JS_DECLARE_NATIVE_FUNCTION(set_full_year);
     JS_DECLARE_NATIVE_FUNCTION(set_full_year);
     JS_DECLARE_NATIVE_FUNCTION(get_hours);
     JS_DECLARE_NATIVE_FUNCTION(get_hours);
+    JS_DECLARE_NATIVE_FUNCTION(set_hours);
     JS_DECLARE_NATIVE_FUNCTION(get_milliseconds);
     JS_DECLARE_NATIVE_FUNCTION(get_milliseconds);
+    JS_DECLARE_NATIVE_FUNCTION(set_milliseconds);
     JS_DECLARE_NATIVE_FUNCTION(get_minutes);
     JS_DECLARE_NATIVE_FUNCTION(get_minutes);
+    JS_DECLARE_NATIVE_FUNCTION(set_minutes);
     JS_DECLARE_NATIVE_FUNCTION(get_month);
     JS_DECLARE_NATIVE_FUNCTION(get_month);
     JS_DECLARE_NATIVE_FUNCTION(get_seconds);
     JS_DECLARE_NATIVE_FUNCTION(get_seconds);
+    JS_DECLARE_NATIVE_FUNCTION(set_seconds);
     JS_DECLARE_NATIVE_FUNCTION(get_time);
     JS_DECLARE_NATIVE_FUNCTION(get_time);
     JS_DECLARE_NATIVE_FUNCTION(get_utc_date);
     JS_DECLARE_NATIVE_FUNCTION(get_utc_date);
     JS_DECLARE_NATIVE_FUNCTION(get_utc_day);
     JS_DECLARE_NATIVE_FUNCTION(get_utc_day);

+ 21 - 0
Userland/Libraries/LibJS/Tests/builtins/Date/Date.prototype.setHours.js

@@ -0,0 +1,21 @@
+test("basic functionality", () => {
+    let d = new Date(2000, 2, 1);
+
+    d.setHours(2);
+    expect(d.getHours()).toBe(2);
+
+    d.setHours(2, 30);
+    expect(d.getHours()).toBe(2);
+    expect(d.getMinutes()).toBe(30);
+
+    d.setHours(2, 30, 50);
+    expect(d.getHours()).toBe(2);
+    expect(d.getMinutes()).toBe(30);
+    expect(d.getSeconds()).toBe(50);
+
+    d.setHours(2, 30, 50, 600);
+    expect(d.getHours()).toBe(2);
+    expect(d.getMinutes()).toBe(30);
+    expect(d.getSeconds()).toBe(50);
+    expect(d.getMilliseconds()).toBe(600);
+});

+ 6 - 0
Userland/Libraries/LibJS/Tests/builtins/Date/Date.prototype.setMilliseconds.js

@@ -0,0 +1,6 @@
+test("basic functionality", () => {
+    let d = new Date(2000, 2, 1);
+
+    d.setMilliseconds(600);
+    expect(d.getMilliseconds()).toBe(600);
+});

+ 15 - 0
Userland/Libraries/LibJS/Tests/builtins/Date/Date.prototype.setMinutes.js

@@ -0,0 +1,15 @@
+test("basic functionality", () => {
+    let d = new Date(2000, 2, 1);
+
+    d.setMinutes(30);
+    expect(d.getMinutes()).toBe(30);
+
+    d.setMinutes(30, 50);
+    expect(d.getMinutes()).toBe(30);
+    expect(d.getSeconds()).toBe(50);
+
+    d.setMinutes(30, 50, 600);
+    expect(d.getMinutes()).toBe(30);
+    expect(d.getSeconds()).toBe(50);
+    expect(d.getMilliseconds()).toBe(600);
+});

+ 10 - 0
Userland/Libraries/LibJS/Tests/builtins/Date/Date.prototype.setSeconds.js

@@ -0,0 +1,10 @@
+test("basic functionality", () => {
+    let d = new Date(2000, 2, 1);
+
+    d.setSeconds(50);
+    expect(d.getSeconds()).toBe(50);
+
+    d.setSeconds(50, 600);
+    expect(d.getSeconds()).toBe(50);
+    expect(d.getMilliseconds()).toBe(600);
+});