summaryrefslogtreecommitdiffstats
path: root/dom/animation/AnimationUtils.h
blob: 0d8c53afa056b9324d443515f6951891950839e7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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_dom_AnimationUtils_h
#define mozilla_dom_AnimationUtils_h

#include "mozilla/PseudoStyleType.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/dom/Nullable.h"
#include "nsRFPService.h"
#include "nsStringFwd.h"

class nsIContent;
class nsIFrame;
struct JSContext;

namespace mozilla {

class EffectSet;

namespace dom {
class Document;
class Element;
}  // namespace dom

class AnimationUtils {
 public:
  using Document = dom::Document;

  static dom::Nullable<double> TimeDurationToDouble(
      const dom::Nullable<TimeDuration>& aTime, RTPCallerType aRTPCallerType) {
    dom::Nullable<double> result;

    if (!aTime.IsNull()) {
      // 0 is an inappropriate mixin for this this area; however CSS Animations
      // needs to have it's Time Reduction Logic refactored, so it's currently
      // only clamping for RFP mode. RFP mode gives a much lower time precision,
      // so we accept the security leak here for now
      result.SetValue(nsRFPService::ReduceTimePrecisionAsMSecsRFPOnly(
          aTime.Value().ToMilliseconds(), 0, aRTPCallerType));
    }

    return result;
  }

  static dom::Nullable<TimeDuration> DoubleToTimeDuration(
      const dom::Nullable<double>& aTime) {
    dom::Nullable<TimeDuration> result;

    if (!aTime.IsNull()) {
      result.SetValue(TimeDuration::FromMilliseconds(aTime.Value()));
    }

    return result;
  }

  static void LogAsyncAnimationFailure(nsCString& aMessage,
                                       const nsIContent* aContent = nullptr);

  /**
   * Get the document from the JS context to use when parsing CSS properties.
   */
  static Document* GetCurrentRealmDocument(JSContext* aCx);

  /**
   * Get the document from the global object, or nullptr if the document has
   * no window, to use when constructing DOM object without entering the
   * target window's compartment (see KeyframeEffect constructor).
   */
  static Document* GetDocumentFromGlobal(JSObject* aGlobalObject);

  /**
   * Returns true if the given frame has an animated scale.
   */
  static bool FrameHasAnimatedScale(const nsIFrame* aFrame);

  /**
   * Returns true if the given (pseudo-)element has any transitions that are
   * current (playing or waiting to play) or in effect (e.g. filling forwards).
   */
  static bool HasCurrentTransitions(const dom::Element* aElement,
                                    PseudoStyleType aPseudoType);

  /**
   * Returns true if this pseudo style type is supported by animations.
   * Note: This doesn't include PseudoStyleType::NotPseudo.
   */
  static bool IsSupportedPseudoForAnimations(PseudoStyleType aType) {
    // FIXME: Bug 1615469: Support first-line and first-letter for Animation.
    return aType == PseudoStyleType::before ||
           aType == PseudoStyleType::after || aType == PseudoStyleType::marker;
  }

  /**
   * Returns true if the difference between |aFirst| and |aSecond| is within
   * the animation time tolerance (i.e. 1 microsecond).
   */
  static bool IsWithinAnimationTimeTolerance(const TimeDuration& aFirst,
                                             const TimeDuration& aSecond) {
    if (aFirst == TimeDuration::Forever() ||
        aSecond == TimeDuration::Forever()) {
      return aFirst == aSecond;
    }

    TimeDuration diff = aFirst >= aSecond ? aFirst - aSecond : aSecond - aFirst;
    return diff <= TimeDuration::FromMicroseconds(1);
  }

  // Returns the target element for restyling.
  //
  // If |aPseudoType| is ::after, ::before or ::marker, returns the generated
  // content element of which |aElement| is the parent. If |aPseudoType| is any
  // other pseudo type (other than PseudoStyleType::NotPseudo) returns nullptr.
  // Otherwise, returns |aElement|.
  static dom::Element* GetElementForRestyle(dom::Element* aElement,
                                            PseudoStyleType aPseudoType);

  // Returns the pair of |Element, PseudoStyleType| from an element which could
  // be an element or a pseudo element (i.e. an element used for restyling and
  // DOM tree).
  //
  // Animation module usually uses a pair of (Element*, PseudoStyleType) to
  // represent the animation target, and the |Element| in the pair is the
  // generated content container if it's a pseudo element.
  static std::pair<const dom::Element*, PseudoStyleType> GetElementPseudoPair(
      const dom::Element* aElementOrPseudo);
};

}  // namespace mozilla

#endif