Files
palemoon27/layout/style/AnimationCommon.h
T
roytam1 011f78a086 import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1253678 - Rename mozilla::Function to mozilla::function. r=froydnj (888553522d)
- Bug 1250788 - Part 2: Expose IsCSSSheetType method. r=bholley (7eb73ec696)
- Bug 1254943 - Set JS execution reason when invoking Promise callbacks. r=bz (212c135941)
- Bug 1175881 - about:sync-log can't read files on OS X with e10s on and content process sandbox enabled. r=areinald (52cf449634)
- Bug 1250788 - Part 3.1: Factor out CSSStyleSheetInner members so they can be used by ServoStyleSheet. r=bholley (4c50adcf26)
- Bug 1250788 - Part 3.2: Factor out CSSStyleSheet members so they can be used by ServoStyleSheet. r=bholley (7f09f8b56e)
- Bug 1250788 - Part 3.3: Implement enough of ServoStyleSheet for Loader to be able to create and parse one. r=bholley (7bb9e8bd47)
- Bug 1251496 - Hoist existing RefPtrTraits into a ServoBindingHelpers.h. r=heycam (c62ad77b46)
- Bug 1242690 - Ensure that mouse events have the callback transform applied. r=botond (296db0746b)
- Bug 1250788 - Part 1: Add interface to create and parse Servo style sheets. r=bholley (c50e5ada02)
- Bug 1250788 - Part 4: Implement enough of ServoStyleSet to handle the UA style sheets being added to it. r=bholley (d0ac9aa262)
- Bug 1250788 - Part 5: Create and parse ServoStyleSheets in css::Loader. r=bholley (25f6b1f8b9)
- Bug 1250788 - Part 6: Create ServoStyleSheets for the pref style sheet. r=bholley (275eb39243)
- Bug 1250788 - Unified build fix. (e52a27ef8d)
- Bug 1250379 - Create css::Loaders for specific style backend types. r=dholbert (a85f56226a)
- Bug 1256500 - Root style contexts before calling ApplyStyleFixups. r=heycam (1b47d3401c)
- Bug 1251496 - Introduce a servo-side data structure to represent the style set. r=heycam (956bd63b56)
- Bug 1252611 - Hoist mDocument into StyleSheet. r=dholbert (993664de79)
- Bug 1252611 - Add a method to get the StyleSheetInfo for a given StyleSheet. r=dholbert (59578e1bfc)
- Bug 1252611 - Hoist IsComplete/SetComplete into StyleSheet. r=dholbert (7e88b78d11)
- Preemptive unified build fix; no bug (100762c5c9)
- Bug 1239945 part 0 - Fix unified build (425e1109bf)
- Bug 1239945 part 1 - Drop a number of animation manager/collection-related methods that are unused (and in some cases undefined); r=dholbert (4d52514fe5)
- Bug 1239945 part 2 - Drop CommonAnimationManager::ContentOrAncestorHasAnimation; r=dholbert (ba0a919dcb)
- Bug 1239945 part 3 - Move AnimationCollection to a separate file; r=dholbert (b6af8d9ff3)
- Bug 1239945 part 4 - Remove the pointer from an AnimationCollection to its manager since it is no longer used; r=dholbert (875581afd5)
- Bug 1239945 part 5 - Use MayHaveAnimations() to return early in CommonAnimationManager::GetAnimationCollection; r=dholbert (aa4e1988e1)
- Bug 1242872 - Part 1: Introduce CSSAnimationBuilder to factor a bunch of stuff in BuildAnimations and CheckAnimationRule out. r=dbaron (25c1002b42)
- Bug 1242872 - Part 2: Set timeline in CSSAnimationBuilder::Build. r=dbaron (fd7461c6cb)
- Bug 1242872 - Part 3: Factor finding old animations process out. r=dbaron (901e5dadae)
- Bug 1242872 - Part 4: Factor updating animation properties process out. r=dbaron (deba9bbc34)
- Bug 1242872 - Part 5: Change CopyPropertiesFrom to UpdateProperties. r=birtles (26cfdf190b)
- Bug 1242872 - Part 6: Trigger a layer update explicitly when copying animation properties. r=birtles (8150212286)
- Bug 1242872 - Part 7: Eliminate creation of temporary animations. r=dbaron (24e0a5b79d)
- Bug 1242872 - Part 8: ElementPropertyTransition::ToValue(). r=birtles (2f21ea5887)
- Bug 1242872 - Part 1.1: Move AnimationManager::BuildAnimations. r=dbaron (6c51d5409d)
- Bug 1242872 - Part 9: Should not assume any order of animations in MurationObserver. r=pbrosset (910c5c0519)
- Bug 1239945 part 6 - Templatize AnimationCollection based on the concrete type of Animation stored; r=dholbert (bb37958019)
- Bug 1239945 part 7 - Move GetAnimationCollection to AnimationCollection; r=dholbert (e254079b58)
- Bug 1239945 part 8 - Add GetOrCreateAnimationCollection; r=dholbert (4e59c24fc1)
- Bug 1244641 - Part 1: Let AnimationEffectTiming have an effect. r=hiro (f2c4e43e80)
- Bug 1244641 - Part 2: Add duration implementation in dom/animation/AnimationEffectTiming.cpp. r=hiro, r=smaug (05819e6b8f)
- Bug 1244641 - Part 3: Notify animation mutation observers from AnimationEffectTiming::SetDuration. r=hiro (12ba42404a)
- Bug 1244080 - Part 0: Remove unnecessary argument for remove(). r=bbirtles (4753fd443d)
- Bug 1244080 - Part 1: Test that setting duration in the middle of the animation causes only once a restyling. r=bbirtles (64d568f0b2)
- Bug 1241692 - Part 1: Ensure that element which is added in each test is removed before subsequent test is processed. r=dholbert (890cce3bb3)
- Bug 1241692 - Part 2: We should observe stylings only for animations. r=dholbert (24e9497037)
- Bug 1218646 - Skip to check whether property can run on compositor or not if mWinsInCascade is false. r=birtles (f59232736b)
- Bug 1244641 - Part 4: Add duration tests in dom/animation/test/chrome. r=hiro (53fd5bdaf3)
- Bug 1244641 - Part 5: Add duration tests in layout/style/test. r=hiro (a5fd00fe51)
- Bug 1244641 - Part 6: Add duration tests in testing/web-platform/tests/web-animations. r=hiro (9ba57998ce)
- Bug 1257422 part 1. Add a way to do IDBObjectStore::OpenCursor without a JSContext if we are not passing a keyrange. r=khuey (a281fffd31)
- Bug 1257422 part 2. Use the overload of IDBRequest::GetResult that doesn't ask for a JSContext in FirstRevisionIdCallback::HandleEvent, since there is no reason not to. r=khuey (1d62d3da69)
2024-02-02 11:08:34 +08:00

284 lines
8.1 KiB
C++

/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_css_AnimationCommon_h
#define mozilla_css_AnimationCommon_h
#include <algorithm> // For <std::stable_sort>
#include "mozilla/AnimationCollection.h"
#include "mozilla/AnimationComparator.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/LinkedList.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/StyleAnimationValue.h"
#include "mozilla/dom/Animation.h"
#include "mozilla/Attributes.h" // For MOZ_NON_OWNING_REF
#include "mozilla/Assertions.h"
#include "nsContentUtils.h"
#include "nsCSSProperty.h"
#include "nsCSSPseudoElements.h"
#include "nsCycleCollectionParticipant.h"
class nsIFrame;
class nsPresContext;
namespace mozilla {
namespace dom {
class Element;
}
template <class AnimationType>
class CommonAnimationManager {
public:
explicit CommonAnimationManager(nsPresContext *aPresContext)
: mPresContext(aPresContext)
{
}
// NOTE: This can return null after Disconnect().
nsPresContext* PresContext() const { return mPresContext; }
/**
* Notify the manager that the pres context is going away.
*/
void Disconnect()
{
// Content nodes might outlive the transition or animation manager.
RemoveAllElementCollections();
mPresContext = nullptr;
}
static bool ExtractComputedValueForTransition(
nsCSSProperty aProperty,
nsStyleContext* aStyleContext,
StyleAnimationValue& aComputedValue);
protected:
virtual ~CommonAnimationManager()
{
MOZ_ASSERT(!mPresContext, "Disconnect should have been called");
}
void AddElementCollection(AnimationCollection<AnimationType>* aCollection)
{
mElementCollections.insertBack(aCollection);
}
void RemoveAllElementCollections()
{
while (AnimationCollection<AnimationType>* head =
mElementCollections.getFirst()) {
head->Destroy(); // Note: this removes 'head' from mElementCollections.
}
}
LinkedList<AnimationCollection<AnimationType>> mElementCollections;
nsPresContext *mPresContext; // weak (non-null from ctor to Disconnect)
};
template <class AnimationType>
/* static */ bool
CommonAnimationManager<AnimationType>::ExtractComputedValueForTransition(
nsCSSProperty aProperty,
nsStyleContext* aStyleContext,
StyleAnimationValue& aComputedValue)
{
bool result = StyleAnimationValue::ExtractComputedValue(aProperty,
aStyleContext,
aComputedValue);
if (aProperty == eCSSProperty_visibility) {
MOZ_ASSERT(aComputedValue.GetUnit() ==
StyleAnimationValue::eUnit_Enumerated,
"unexpected unit");
aComputedValue.SetIntValue(aComputedValue.GetIntValue(),
StyleAnimationValue::eUnit_Visibility);
}
return result;
}
/**
* Utility class for referencing the element that created a CSS animation or
* transition. It is non-owning (i.e. it uses a raw pointer) since it is only
* expected to be set by the owned animation while it actually being managed
* by the owning element.
*
* This class also abstracts the comparison of an element/pseudo-class pair
* for the sake of composite ordering since this logic is common to both CSS
* animations and transitions.
*
* (We call this OwningElementRef instead of just OwningElement so that we can
* call the getter on CSSAnimation/CSSTransition OwningElement() without
* clashing with this object's contructor.)
*/
class OwningElementRef final
{
public:
OwningElementRef()
: mElement(nullptr)
, mPseudoType(CSSPseudoElementType::NotPseudo)
{ }
OwningElementRef(dom::Element& aElement,
CSSPseudoElementType aPseudoType)
: mElement(&aElement)
, mPseudoType(aPseudoType)
{ }
bool Equals(const OwningElementRef& aOther) const
{
return mElement == aOther.mElement &&
mPseudoType == aOther.mPseudoType;
}
bool LessThan(const OwningElementRef& aOther) const
{
MOZ_ASSERT(mElement && aOther.mElement,
"Elements to compare should not be null");
if (mElement != aOther.mElement) {
return nsContentUtils::PositionIsBefore(mElement, aOther.mElement);
}
return mPseudoType == CSSPseudoElementType::NotPseudo ||
(mPseudoType == CSSPseudoElementType::before &&
aOther.mPseudoType == CSSPseudoElementType::after);
}
bool IsSet() const { return !!mElement; }
void GetElement(dom::Element*& aElement,
CSSPseudoElementType& aPseudoType) const {
aElement = mElement;
aPseudoType = mPseudoType;
}
nsPresContext* GetRenderedPresContext() const;
private:
dom::Element* MOZ_NON_OWNING_REF mElement;
CSSPseudoElementType mPseudoType;
};
template <class EventInfo>
class DelayedEventDispatcher
{
public:
DelayedEventDispatcher() : mIsSorted(true) { }
void QueueEvent(EventInfo&& aEventInfo)
{
mPendingEvents.AppendElement(Forward<EventInfo>(aEventInfo));
mIsSorted = false;
}
// This is exposed as a separate method so that when we are dispatching
// *both* transition events and animation events we can sort both lists
// once using the current state of the document before beginning any
// dispatch.
void SortEvents()
{
if (mIsSorted) {
return;
}
// FIXME: Replace with mPendingEvents.StableSort when bug 1147091 is
// fixed.
std::stable_sort(mPendingEvents.begin(), mPendingEvents.end(),
EventInfoLessThan());
mIsSorted = true;
}
// Takes a reference to the owning manager's pres context so it can
// detect if the pres context is destroyed while dispatching one of
// the events.
//
// This will call SortEvents automatically if it has not already been
// called.
void DispatchEvents(nsPresContext* const & aPresContext)
{
if (!aPresContext || mPendingEvents.IsEmpty()) {
return;
}
SortEvents();
EventArray events;
mPendingEvents.SwapElements(events);
// mIsSorted will be set to true by SortEvents above, and we leave it
// that way since mPendingEvents is now empty
for (EventInfo& info : events) {
EventDispatcher::Dispatch(info.mElement, aPresContext, &info.mEvent);
if (!aPresContext) {
break;
}
}
}
void ClearEventQueue()
{
mPendingEvents.Clear();
mIsSorted = true;
}
bool HasQueuedEvents() const { return !mPendingEvents.IsEmpty(); }
// Methods for supporting cycle-collection
void Traverse(nsCycleCollectionTraversalCallback* aCallback,
const char* aName)
{
for (EventInfo& info : mPendingEvents) {
ImplCycleCollectionTraverse(*aCallback, info.mElement, aName);
ImplCycleCollectionTraverse(*aCallback, info.mAnimation, aName);
}
}
void Unlink() { ClearEventQueue(); }
protected:
class EventInfoLessThan
{
public:
bool operator()(const EventInfo& a, const EventInfo& b) const
{
if (a.mTimeStamp != b.mTimeStamp) {
// Null timestamps sort first
if (a.mTimeStamp.IsNull() || b.mTimeStamp.IsNull()) {
return a.mTimeStamp.IsNull();
} else {
return a.mTimeStamp < b.mTimeStamp;
}
}
AnimationPtrComparator<RefPtr<dom::Animation>> comparator;
return comparator.LessThan(a.mAnimation, b.mAnimation);
}
};
typedef nsTArray<EventInfo> EventArray;
EventArray mPendingEvents;
bool mIsSorted;
};
template <class EventInfo>
inline void
ImplCycleCollectionUnlink(DelayedEventDispatcher<EventInfo>& aField)
{
aField.Unlink();
}
template <class EventInfo>
inline void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
DelayedEventDispatcher<EventInfo>& aField,
const char* aName,
uint32_t aFlags = 0)
{
aField.Traverse(&aCallback, aName);
}
} // namespace mozilla
#endif /* !defined(mozilla_css_AnimationCommon_h) */