LibJS: Start implementing Date :^)
This adds: - A global Date object (with `length` property and `now` function) - The Date constructor (no arguments yet) - The Date prototype (with `get*` functions)
This commit is contained in:
parent
5c779c124b
commit
d4e3688f4f
Notes:
sideshowbarker
2024-07-19 08:03:11 +09:00
Author: https://github.com/linusg Commit: https://github.com/SerenityOS/serenity/commit/d4e3688f4f5 Pull-request: https://github.com/SerenityOS/serenity/pull/1533 Reviewed-by: https://github.com/awesomekling
25 changed files with 567 additions and 5 deletions
29
Base/home/anon/js/date.js
Normal file
29
Base/home/anon/js/date.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
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;
|
||||
}
|
||||
console.log("Date: " + year + "-" + month + "-" + day);
|
||||
console.log("Time: " + hours + ":" + minutes + ":" + seconds + "." + milliseconds);
|
|
@ -28,6 +28,7 @@
|
|||
#include <LibJS/AST.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/ArrayPrototype.h>
|
||||
#include <LibJS/Runtime/DatePrototype.h>
|
||||
#include <LibJS/Runtime/Error.h>
|
||||
#include <LibJS/Runtime/ErrorPrototype.h>
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
|
@ -46,6 +47,7 @@ Interpreter::Interpreter()
|
|||
m_string_prototype = heap().allocate<StringPrototype>();
|
||||
m_array_prototype = heap().allocate<ArrayPrototype>();
|
||||
m_error_prototype = heap().allocate<ErrorPrototype>();
|
||||
m_date_prototype = heap().allocate<DatePrototype>();
|
||||
|
||||
m_global_object = heap().allocate<GlobalObject>();
|
||||
}
|
||||
|
@ -165,6 +167,7 @@ void Interpreter::gather_roots(Badge<Heap>, HashTable<Cell*>& roots)
|
|||
roots.set(m_object_prototype);
|
||||
roots.set(m_array_prototype);
|
||||
roots.set(m_error_prototype);
|
||||
roots.set(m_date_prototype);
|
||||
|
||||
roots.set(m_exception);
|
||||
|
||||
|
|
|
@ -111,6 +111,7 @@ public:
|
|||
Object* object_prototype() { return m_object_prototype; }
|
||||
Object* array_prototype() { return m_array_prototype; }
|
||||
Object* error_prototype() { return m_error_prototype; }
|
||||
Object* date_prototype() { return m_date_prototype; }
|
||||
|
||||
Exception* exception() { return m_exception; }
|
||||
void clear_exception() { m_exception = nullptr; }
|
||||
|
@ -138,6 +139,7 @@ private:
|
|||
Object* m_object_prototype { nullptr };
|
||||
Object* m_array_prototype { nullptr };
|
||||
Object* m_error_prototype { nullptr };
|
||||
Object* m_date_prototype { nullptr };
|
||||
|
||||
Exception* m_exception { nullptr };
|
||||
|
||||
|
|
|
@ -10,6 +10,9 @@ OBJS = \
|
|||
Runtime/ArrayPrototype.o \
|
||||
Runtime/Cell.o \
|
||||
Runtime/ConsoleObject.o \
|
||||
Runtime/Date.o \
|
||||
Runtime/DateConstructor.o \
|
||||
Runtime/DatePrototype.o \
|
||||
Runtime/Error.o \
|
||||
Runtime/ErrorPrototype.o \
|
||||
Runtime/Exception.o \
|
||||
|
|
44
Libraries/LibJS/Runtime/Date.cpp
Normal file
44
Libraries/LibJS/Runtime/Date.cpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Linus Groh <mail@linusgroh.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <LibCore/DateTime.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/Date.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
Date::Date(Core::DateTime datetime, u16 milliseconds)
|
||||
: m_datetime(datetime)
|
||||
, m_milliseconds(milliseconds)
|
||||
{
|
||||
set_prototype(interpreter().date_prototype());
|
||||
}
|
||||
|
||||
Date::~Date()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
52
Libraries/LibJS/Runtime/Date.h
Normal file
52
Libraries/LibJS/Runtime/Date.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Linus Groh <mail@linusgroh.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <LibCore/DateTime.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
class Date final : public Object {
|
||||
public:
|
||||
Date(Core::DateTime datetime, u16 milliseconds);
|
||||
virtual ~Date() override;
|
||||
|
||||
Core::DateTime& datetime() { return m_datetime; }
|
||||
u16 milliseconds() { return m_milliseconds; }
|
||||
virtual Value value_of() const override
|
||||
{
|
||||
return Value(static_cast<double>(m_datetime.timestamp() * 1000 + m_milliseconds));
|
||||
}
|
||||
|
||||
private:
|
||||
virtual bool is_date() const final { return true; }
|
||||
virtual const char* class_name() const override { return "Date"; }
|
||||
|
||||
Core::DateTime m_datetime;
|
||||
u16 m_milliseconds;
|
||||
};
|
||||
|
||||
}
|
65
Libraries/LibJS/Runtime/DateConstructor.cpp
Normal file
65
Libraries/LibJS/Runtime/DateConstructor.cpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Linus Groh <mail@linusgroh.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <LibCore/DateTime.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/Date.h>
|
||||
#include <LibJS/Runtime/DateConstructor.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
DateConstructor::DateConstructor()
|
||||
{
|
||||
put("prototype", interpreter().date_prototype());
|
||||
put("length", Value(7));
|
||||
|
||||
put_native_function("now", now);
|
||||
}
|
||||
|
||||
DateConstructor::~DateConstructor()
|
||||
{
|
||||
}
|
||||
|
||||
Value DateConstructor::call(Interpreter& interpreter)
|
||||
{
|
||||
// TODO: Support args
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
auto datetime = Core::DateTime::now();
|
||||
auto milliseconds = static_cast<u16>(tv.tv_usec / 1000);
|
||||
return interpreter.heap().allocate<Date>(datetime, milliseconds);
|
||||
}
|
||||
|
||||
Value DateConstructor::now(Interpreter&)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
return Value(tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0);
|
||||
}
|
||||
|
||||
}
|
46
Libraries/LibJS/Runtime/DateConstructor.h
Normal file
46
Libraries/LibJS/Runtime/DateConstructor.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Linus Groh <mail@linusgroh.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibJS/Runtime/NativeFunction.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
class DateConstructor final : public NativeFunction {
|
||||
public:
|
||||
DateConstructor();
|
||||
virtual ~DateConstructor() override;
|
||||
|
||||
virtual Value call(Interpreter&) override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "DateConstructor"; }
|
||||
|
||||
static Value now(Interpreter&);
|
||||
};
|
||||
|
||||
}
|
149
Libraries/LibJS/Runtime/DatePrototype.cpp
Normal file
149
Libraries/LibJS/Runtime/DatePrototype.cpp
Normal file
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Linus Groh <mail@linusgroh.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <AK/String.h>
|
||||
#include <LibCore/DateTime.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/Date.h>
|
||||
#include <LibJS/Runtime/DatePrototype.h>
|
||||
#include <LibJS/Runtime/Error.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
static Date* this_date_from_interpreter(Interpreter& interpreter)
|
||||
{
|
||||
auto* this_object = interpreter.this_value().to_object(interpreter.heap());
|
||||
if (!this_object)
|
||||
return nullptr;
|
||||
if (!this_object->is_date()) {
|
||||
interpreter.throw_exception<Error>("TypeError", "object must be of type Date");
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<Date*>(this_object);
|
||||
}
|
||||
|
||||
DatePrototype::DatePrototype()
|
||||
{
|
||||
put_native_function("getDate", get_date);
|
||||
put_native_function("getDay", get_day);
|
||||
put_native_function("getFullYear", get_full_year);
|
||||
put_native_function("getHours", get_hours);
|
||||
put_native_function("getMilliseconds", get_milliseconds);
|
||||
put_native_function("getMinutes", get_minutes);
|
||||
put_native_function("getMonth", get_month);
|
||||
put_native_function("getSeconds", get_seconds);
|
||||
put_native_function("getTime", get_time);
|
||||
}
|
||||
|
||||
DatePrototype::~DatePrototype()
|
||||
{
|
||||
}
|
||||
|
||||
Value DatePrototype::get_date(Interpreter& interpreter)
|
||||
{
|
||||
auto* this_object = this_date_from_interpreter(interpreter);
|
||||
if (!this_object)
|
||||
return {};
|
||||
auto date = this_object->datetime().day();
|
||||
return Value(static_cast<double>(date));
|
||||
}
|
||||
|
||||
Value DatePrototype::get_day(Interpreter& interpreter)
|
||||
{
|
||||
auto* this_object = this_date_from_interpreter(interpreter);
|
||||
if (!this_object)
|
||||
return {};
|
||||
auto day = this_object->datetime().weekday();
|
||||
return Value(static_cast<double>(day));
|
||||
}
|
||||
|
||||
Value DatePrototype::get_full_year(Interpreter& interpreter)
|
||||
{
|
||||
auto* this_object = this_date_from_interpreter(interpreter);
|
||||
if (!this_object)
|
||||
return {};
|
||||
auto full_year = this_object->datetime().year();
|
||||
return Value(static_cast<double>(full_year));
|
||||
}
|
||||
|
||||
Value DatePrototype::get_hours(Interpreter& interpreter)
|
||||
{
|
||||
auto* this_object = this_date_from_interpreter(interpreter);
|
||||
if (!this_object)
|
||||
return {};
|
||||
auto hours = this_object->datetime().hour();
|
||||
return Value(static_cast<double>(hours));
|
||||
}
|
||||
|
||||
Value DatePrototype::get_milliseconds(Interpreter& interpreter)
|
||||
{
|
||||
auto* this_object = this_date_from_interpreter(interpreter);
|
||||
if (!this_object)
|
||||
return {};
|
||||
auto milliseconds = this_object->milliseconds();
|
||||
return Value(static_cast<double>(milliseconds));
|
||||
}
|
||||
|
||||
Value DatePrototype::get_minutes(Interpreter& interpreter)
|
||||
{
|
||||
auto* this_object = this_date_from_interpreter(interpreter);
|
||||
if (!this_object)
|
||||
return {};
|
||||
auto minutes = this_object->datetime().minute();
|
||||
return Value(static_cast<double>(minutes));
|
||||
}
|
||||
|
||||
Value DatePrototype::get_month(Interpreter& interpreter)
|
||||
{
|
||||
auto* this_object = this_date_from_interpreter(interpreter);
|
||||
if (!this_object)
|
||||
return {};
|
||||
auto months = this_object->datetime().month() - 1;
|
||||
return Value(static_cast<double>(months));
|
||||
}
|
||||
|
||||
Value DatePrototype::get_seconds(Interpreter& interpreter)
|
||||
{
|
||||
auto* this_object = this_date_from_interpreter(interpreter);
|
||||
if (!this_object)
|
||||
return {};
|
||||
auto seconds = this_object->datetime().second();
|
||||
return Value(static_cast<double>(seconds));
|
||||
}
|
||||
|
||||
Value DatePrototype::get_time(Interpreter& interpreter)
|
||||
{
|
||||
auto* this_object = this_date_from_interpreter(interpreter);
|
||||
if (!this_object)
|
||||
return {};
|
||||
auto seconds = this_object->datetime().timestamp();
|
||||
auto milliseconds = this_object->milliseconds();
|
||||
return Value(static_cast<double>(seconds * 1000 + milliseconds));
|
||||
}
|
||||
|
||||
}
|
52
Libraries/LibJS/Runtime/DatePrototype.h
Normal file
52
Libraries/LibJS/Runtime/DatePrototype.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Linus Groh <mail@linusgroh.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
class DatePrototype final : public Object {
|
||||
public:
|
||||
DatePrototype();
|
||||
virtual ~DatePrototype() override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "DatePrototype"; }
|
||||
|
||||
static Value get_date(Interpreter&);
|
||||
static Value get_day(Interpreter&);
|
||||
static Value get_full_year(Interpreter&);
|
||||
static Value get_hours(Interpreter&);
|
||||
static Value get_milliseconds(Interpreter&);
|
||||
static Value get_minutes(Interpreter&);
|
||||
static Value get_month(Interpreter&);
|
||||
static Value get_seconds(Interpreter&);
|
||||
static Value get_time(Interpreter&);
|
||||
};
|
||||
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
#include <LibJS/Heap/Heap.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/ConsoleObject.h>
|
||||
#include <LibJS/Runtime/DateConstructor.h>
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
#include <LibJS/Runtime/MathObject.h>
|
||||
#include <LibJS/Runtime/NativeFunction.h>
|
||||
|
@ -17,6 +18,7 @@ GlobalObject::GlobalObject()
|
|||
put_native_function("isNaN", is_nan);
|
||||
|
||||
put("console", heap().allocate<ConsoleObject>());
|
||||
put("Date", heap().allocate<DateConstructor>());
|
||||
put("Math", heap().allocate<MathObject>());
|
||||
put("Object", heap().allocate<ObjectConstructor>());
|
||||
}
|
||||
|
|
|
@ -49,12 +49,13 @@ public:
|
|||
void put_native_function(const FlyString& property_name, AK::Function<Value(Interpreter&)>);
|
||||
void put_native_property(const FlyString& property_name, AK::Function<Value(Interpreter&)> getter, AK::Function<void(Interpreter&, Value)> setter);
|
||||
|
||||
virtual bool is_error() const { return false; }
|
||||
virtual bool is_array() const { return false; }
|
||||
virtual bool is_date() const { return false; }
|
||||
virtual bool is_error() const { return false; }
|
||||
virtual bool is_function() const { return false; }
|
||||
virtual bool is_native_function() const { return false; }
|
||||
virtual bool is_string_object() const { return false; }
|
||||
virtual bool is_native_property() const { return false; }
|
||||
virtual bool is_string_object() const { return false; }
|
||||
|
||||
virtual const char* class_name() const override { return "Object"; }
|
||||
virtual void visit_children(Cell::Visitor&) override;
|
||||
|
|
|
@ -58,7 +58,7 @@ String Value::to_string() const
|
|||
return "NaN";
|
||||
|
||||
// FIXME: This needs improvement.
|
||||
return String::number((i32)as_double());
|
||||
return String::format("%f", as_double());
|
||||
}
|
||||
|
||||
if (is_object())
|
||||
|
|
|
@ -53,7 +53,7 @@ public:
|
|||
bool is_cell() const { return is_string() || is_object(); }
|
||||
bool is_array() const;
|
||||
|
||||
bool is_nan() const { return is_number() && __builtin_isnan( as_double()); }
|
||||
bool is_nan() const { return is_number() && __builtin_isnan(as_double()); }
|
||||
|
||||
Value()
|
||||
: m_type(Type::Undefined)
|
||||
|
|
15
Libraries/LibJS/Tests/Date.now.js
Normal file
15
Libraries/LibJS/Tests/Date.now.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
function assert(x) { if (!x) throw 1; }
|
||||
|
||||
try {
|
||||
var last = 0;
|
||||
for (var i = 0; i < 100; ++i) {
|
||||
var now = Date.now();
|
||||
assert(!isNaN(now))
|
||||
assert(now > 1580000000000);
|
||||
assert(now >= last);
|
||||
last = now;
|
||||
}
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
11
Libraries/LibJS/Tests/Date.prototype.getDate.js
Normal file
11
Libraries/LibJS/Tests/Date.prototype.getDate.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
function assert(x) { if (!x) throw 1; }
|
||||
|
||||
try {
|
||||
var d = new Date();
|
||||
assert(!isNaN(d.getDate()));
|
||||
assert(1 <= d.getDate() <= 31);
|
||||
assert(d.getDate() === d.getDate());
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
11
Libraries/LibJS/Tests/Date.prototype.getDay.js
Normal file
11
Libraries/LibJS/Tests/Date.prototype.getDay.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
function assert(x) { if (!x) throw 1; }
|
||||
|
||||
try {
|
||||
var d = new Date();
|
||||
assert(!isNaN(d.getDay()));
|
||||
assert(0 <= d.getDay() <= 6);
|
||||
assert(d.getDay() === d.getDay());
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
11
Libraries/LibJS/Tests/Date.prototype.getFullYear.js
Normal file
11
Libraries/LibJS/Tests/Date.prototype.getFullYear.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
function assert(x) { if (!x) throw 1; }
|
||||
|
||||
try {
|
||||
var d = new Date();
|
||||
assert(!isNaN(d.getFullYear()));
|
||||
assert(d.getFullYear() >= 2020);
|
||||
assert(d.getFullYear() === d.getFullYear());
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
11
Libraries/LibJS/Tests/Date.prototype.getHours.js
Normal file
11
Libraries/LibJS/Tests/Date.prototype.getHours.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
function assert(x) { if (!x) throw 1; }
|
||||
|
||||
try {
|
||||
var d = new Date();
|
||||
assert(!isNaN(d.getHours()));
|
||||
assert(0 <= d.getHours() <= 23);
|
||||
assert(d.getHours() === d.getHours());
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
11
Libraries/LibJS/Tests/Date.prototype.getMilliseconds.js
Normal file
11
Libraries/LibJS/Tests/Date.prototype.getMilliseconds.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
function assert(x) { if (!x) throw 1; }
|
||||
|
||||
try {
|
||||
var d = new Date();
|
||||
assert(!isNaN(d.getMilliseconds()));
|
||||
assert(0 <= d.getMilliseconds() <= 999);
|
||||
assert(d.getMilliseconds() === d.getMilliseconds());
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
11
Libraries/LibJS/Tests/Date.prototype.getMinutes.js
Normal file
11
Libraries/LibJS/Tests/Date.prototype.getMinutes.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
function assert(x) { if (!x) throw 1; }
|
||||
|
||||
try {
|
||||
var d = new Date();
|
||||
assert(!isNaN(d.getMinutes()));
|
||||
assert(0 <= d.getMinutes() <= 59);
|
||||
assert(d.getMinutes() === d.getMinutes());
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
11
Libraries/LibJS/Tests/Date.prototype.getMonth.js
Normal file
11
Libraries/LibJS/Tests/Date.prototype.getMonth.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
function assert(x) { if (!x) throw 1; }
|
||||
|
||||
try {
|
||||
var d = new Date();
|
||||
assert(!isNaN(d.getMonth()));
|
||||
assert(0 <= d.getMonth() <= 11);
|
||||
assert(d.getMonth() === d.getMonth());
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
11
Libraries/LibJS/Tests/Date.prototype.getSeconds.js
Normal file
11
Libraries/LibJS/Tests/Date.prototype.getSeconds.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
function assert(x) { if (!x) throw 1; }
|
||||
|
||||
try {
|
||||
var d = new Date();
|
||||
assert(!isNaN(d.getSeconds()));
|
||||
assert(0 <= d.getSeconds() <= 59);
|
||||
assert(d.getSeconds() === d.getSeconds());
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
11
Libraries/LibJS/Tests/Date.prototype.getTime.js
Normal file
11
Libraries/LibJS/Tests/Date.prototype.getTime.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
function assert(x) { if (!x) throw 1; }
|
||||
|
||||
try {
|
||||
var d = new Date();
|
||||
assert(!isNaN(d.getTime()));
|
||||
assert(d.getTime() > 1580000000000);
|
||||
assert(d.getTime() === d.getTime());
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
|
@ -4,7 +4,7 @@ APPS = ${SRCS:.cpp=}
|
|||
|
||||
EXTRA_CLEAN = $(APPS)
|
||||
|
||||
LIB_DEPS = Web GUI Gfx Audio Protocol IPC Thread Pthread Core PCIDB Markdown JS
|
||||
LIB_DEPS = Web GUI Gfx Audio Protocol IPC Thread Pthread PCIDB Markdown JS Core
|
||||
|
||||
include ../Makefile.common
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue