/* * Copyright (c) 2024, circl * Copyright (c) 2025, Feng Yu * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include namespace Web::DOM { template concept DocumentOrShadowRoot = OneOf; // https://html.spec.whatwg.org/multipage/interaction.html#dom-documentorshadowroot-activeelement template GC::Ptr calculate_active_element(T& self) { // 1. Let candidate be this's node document's focused area's DOM anchor. Node* candidate = self.document().focused_area(); // 2. Set candidate to the result of retargeting candidate against this. candidate = as(retarget(candidate, &self)); // 3. If candidate's root is not this, then return null. if (!candidate || &candidate->root() != &self) return nullptr; // 4. If candidate is not a Document object, then return candidate. if (!is(candidate)) return as(candidate); auto* candidate_document = as_if(candidate); // 5. If candidate has a body element, then return that body element. if (auto* body = candidate_document->body()) return body; // 6. If candidate's document element is non-null, then return that document element. if (auto* document_element = candidate_document->document_element()) return document_element; // 7. Return null. return nullptr; } // https://drafts.csswg.org/web-animations-1/#dom-documentorshadowroot-getanimations template WebIDL::ExceptionOr>> calculate_get_animations(T& self) { // Returns the set of relevant animations for a subtree for the document or shadow root on which this // method is called. Vector> relevant_animations; TRY(self.template for_each_child_of_type_fallible([&](auto& child) -> WebIDL::ExceptionOr { relevant_animations.extend(TRY(child.get_animations_internal( Animations::Animatable::GetAnimationsSorted::No, Animations::GetAnimationsOptions { .subtree = true }))); return IterationDecision::Continue; })); // The returned list is sorted using the composite order described for the associated animations of // effects in § 5.4.2 The effect stack. quick_sort(relevant_animations, [](GC::Ref& a, GC::Ref& b) { auto& a_effect = as(*a->effect()); auto& b_effect = as(*b->effect()); return Animations::KeyframeEffect::composite_order(a_effect, b_effect) < 0; }); // Calling this method triggers a style change event for the document. As a result, the returned list // reflects the state after applying any pending style changes to animation such as changes to // animation-related style properties that have yet to be processed. // FIXME: Implement this. return relevant_animations; } }