From 734076946b767911ed147e3b456e453161ad6b5b Mon Sep 17 00:00:00 2001 From: Matthew Olsson Date: Sat, 4 Nov 2023 08:32:30 -0700 Subject: [PATCH] LibWeb: Add DocumentTimeline IDL object --- .../LibWeb/Animations/DocumentTimeline.cpp | 80 +++++++++++++++++++ .../LibWeb/Animations/DocumentTimeline.h | 42 ++++++++++ .../LibWeb/Animations/DocumentTimeline.idl | 13 +++ Userland/Libraries/LibWeb/CMakeLists.txt | 1 + Userland/Libraries/LibWeb/Forward.h | 1 + Userland/Libraries/LibWeb/idl_files.cmake | 1 + 6 files changed, 138 insertions(+) create mode 100644 Userland/Libraries/LibWeb/Animations/DocumentTimeline.cpp create mode 100644 Userland/Libraries/LibWeb/Animations/DocumentTimeline.h create mode 100644 Userland/Libraries/LibWeb/Animations/DocumentTimeline.idl diff --git a/Userland/Libraries/LibWeb/Animations/DocumentTimeline.cpp b/Userland/Libraries/LibWeb/Animations/DocumentTimeline.cpp new file mode 100644 index 0000000000..6484f792c0 --- /dev/null +++ b/Userland/Libraries/LibWeb/Animations/DocumentTimeline.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2023, Matthew Olsson . + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include + +namespace Web::Animations { + +JS::NonnullGCPtr DocumentTimeline::create(JS::Realm& realm, DOM::Document& document, HighResolutionTime::DOMHighResTimeStamp origin_time) +{ + return realm.heap().allocate(realm, realm, document, origin_time); +} + +// https://www.w3.org/TR/web-animations-1/#dom-documenttimeline-documenttimeline +WebIDL::ExceptionOr> DocumentTimeline::construct_impl(JS::Realm& realm, DocumentTimelineOptions options) +{ + // Creates a new DocumentTimeline. The Document with which the timeline is associated is the Document associated + // with the Window that is the current global object. + auto& window = verify_cast(realm.global_object()); + return create(realm, window.associated_document(), options.origin_time); +} + +// https://www.w3.org/TR/web-animations-1/#ref-for-timeline-time-to-origin-relative-time +Optional DocumentTimeline::convert_a_timeline_time_to_an_original_relative_time(Optional timeline_time) +{ + // To convert a timeline time, timeline time, to an origin-relative time for a document timeline, timeline, return + // the sum of the timeline time and timeline’s origin time. If timeline is inactive, return an unresolved time + // value. + if (is_inactive() || !timeline_time.has_value()) + return {}; + return timeline_time.value() + m_origin_time; +} + +// https://www.w3.org/TR/web-animations-1/#origin-time +WebIDL::ExceptionOr DocumentTimeline::set_current_time(Optional current_time) +{ + // A document timeline is a type of timeline that is associated with a document and whose current time is calculated + // as a fixed offset from the now timestamp provided each time the update animations and send events procedure is + // run. This fixed offset is referred to as the document timeline’s origin time. + if (!current_time.has_value()) + TRY(Base::set_current_time({})); + else + TRY(Base::set_current_time(current_time.value() - m_origin_time)); + + // After a document timeline becomes active, it is monotonically increasing. + if (!is_inactive()) + VERIFY(is_monotonically_increasing()); + + return {}; +} + +// https://www.w3.org/TR/web-animations-1/#document-timelines +bool DocumentTimeline::is_inactive() const +{ + // A document timeline that is associated with a Document which is not an active document is also considered to be + // inactive. + return Base::is_inactive() || !associated_document()->is_active(); +} + +DocumentTimeline::DocumentTimeline(JS::Realm& realm, DOM::Document& document, HighResolutionTime::DOMHighResTimeStamp origin_time) + : AnimationTimeline(realm) + , m_origin_time(origin_time) +{ + set_associated_document(document); +} + +void DocumentTimeline::initialize(JS::Realm& realm) +{ + Base::initialize(realm); + set_prototype(&Bindings::ensure_web_prototype(realm, "DocumentTimeline")); +} + +} diff --git a/Userland/Libraries/LibWeb/Animations/DocumentTimeline.h b/Userland/Libraries/LibWeb/Animations/DocumentTimeline.h new file mode 100644 index 0000000000..6d24b79743 --- /dev/null +++ b/Userland/Libraries/LibWeb/Animations/DocumentTimeline.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023, Matthew Olsson . + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include + +namespace Web::Animations { + +// https://www.w3.org/TR/web-animations-1/#dictdef-documenttimelineoptions +struct DocumentTimelineOptions { + HighResolutionTime::DOMHighResTimeStamp origin_time { 0.0 }; +}; + +// https://www.w3.org/TR/web-animations-1/#the-documenttimeline-interface +class DocumentTimeline : public AnimationTimeline { + WEB_PLATFORM_OBJECT(DocumentTimeline, AnimationTimeline); + +public: + static JS::NonnullGCPtr create(JS::Realm&, DOM::Document&, HighResolutionTime::DOMHighResTimeStamp origin_time); + static WebIDL::ExceptionOr> construct_impl(JS::Realm&, DocumentTimelineOptions options = {}); + + virtual WebIDL::ExceptionOr set_current_time(Optional current_time) override; + virtual bool is_inactive() const override; + + virtual Optional convert_a_timeline_time_to_an_original_relative_time(Optional) override; + virtual bool can_convert_a_timeline_time_to_an_original_relative_time() const override { return true; } + +private: + DocumentTimeline(JS::Realm&, DOM::Document&, HighResolutionTime::DOMHighResTimeStamp origin_time); + + virtual void initialize(JS::Realm&) override; + + HighResolutionTime::DOMHighResTimeStamp m_origin_time; +}; + +} diff --git a/Userland/Libraries/LibWeb/Animations/DocumentTimeline.idl b/Userland/Libraries/LibWeb/Animations/DocumentTimeline.idl new file mode 100644 index 0000000000..1a86c26543 --- /dev/null +++ b/Userland/Libraries/LibWeb/Animations/DocumentTimeline.idl @@ -0,0 +1,13 @@ +#import +#import + +// https://www.w3.org/TR/web-animations-1/#dictdef-documenttimelineoptions +dictionary DocumentTimelineOptions { + DOMHighResTimeStamp originTime = 0; +}; + +// https://www.w3.org/TR/web-animations-1/#documenttimeline +[Exposed=Window] +interface DocumentTimeline : AnimationTimeline { + constructor(optional DocumentTimelineOptions options = {}); +}; diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index d7140cec90..303d14ef60 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -3,6 +3,7 @@ include(accelerated_graphics) set(SOURCES Animations/AnimationTimeline.cpp + Animations/DocumentTimeline.cpp ARIA/AriaData.cpp ARIA/ARIAMixin.cpp ARIA/Roles.cpp diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index 01923d8d92..150d859c55 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -28,6 +28,7 @@ class RecordingPainter; namespace Web::Animations { class AnimationTimeline; +class DocumentTimeline; } namespace Web::ARIA { diff --git a/Userland/Libraries/LibWeb/idl_files.cmake b/Userland/Libraries/LibWeb/idl_files.cmake index 73b439b3d0..bf200d5d99 100644 --- a/Userland/Libraries/LibWeb/idl_files.cmake +++ b/Userland/Libraries/LibWeb/idl_files.cmake @@ -2,6 +2,7 @@ # It is defined here so that there is no need to go to the Meta directory when adding new idl files libweb_js_bindings(Animations/AnimationTimeline) +libweb_js_bindings(Animations/DocumentTimeline) libweb_js_bindings(Crypto/Crypto) libweb_js_bindings(Crypto/SubtleCrypto) libweb_js_bindings(CSS/CSSConditionRule)