AnimationUtils.cpp (4137B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "AnimationUtils.h" 8 9 #include "mozilla/EffectSet.h" 10 #include "mozilla/dom/Animation.h" 11 #include "mozilla/dom/Document.h" 12 #include "mozilla/dom/KeyframeEffect.h" 13 #include "nsAtom.h" 14 #include "nsDebug.h" 15 #include "nsGlobalWindowInner.h" 16 #include "nsIContent.h" 17 #include "nsLayoutUtils.h" 18 #include "nsString.h" 19 #include "xpcpublic.h" // For xpc::NativeGlobal 20 21 using namespace mozilla::dom; 22 23 namespace mozilla { 24 25 /* static */ 26 void AnimationUtils::LogAsyncAnimationFailure(nsCString& aMessage, 27 const nsIContent* aContent) { 28 if (aContent) { 29 aMessage.AppendLiteral(" ["); 30 aMessage.Append(nsAtomCString(aContent->NodeInfo()->NameAtom())); 31 32 nsAtom* id = aContent->GetID(); 33 if (id) { 34 aMessage.AppendLiteral(" with id '"); 35 aMessage.Append(nsAtomCString(aContent->GetID())); 36 aMessage.Append('\''); 37 } 38 aMessage.Append(']'); 39 } 40 aMessage.Append('\n'); 41 printf_stderr("%s", aMessage.get()); 42 } 43 44 /* static */ 45 Document* AnimationUtils::GetCurrentRealmDocument(JSContext* aCx) { 46 nsGlobalWindowInner* win = xpc::CurrentWindowOrNull(aCx); 47 if (!win) { 48 return nullptr; 49 } 50 return win->GetDoc(); 51 } 52 53 /* static */ 54 Document* AnimationUtils::GetDocumentFromGlobal(JSObject* aGlobalObject) { 55 nsGlobalWindowInner* win = xpc::WindowOrNull(aGlobalObject); 56 if (!win) { 57 return nullptr; 58 } 59 return win->GetDoc(); 60 } 61 62 /* static */ 63 bool AnimationUtils::FrameHasAnimatedScale(const nsIFrame* aFrame) { 64 EffectSet* effectSet = EffectSet::GetForFrame( 65 aFrame, nsCSSPropertyIDSet::TransformLikeProperties()); 66 if (!effectSet) { 67 return false; 68 } 69 70 for (const dom::KeyframeEffect* effect : *effectSet) { 71 if (effect->ContainsAnimatedScale(aFrame)) { 72 return true; 73 } 74 } 75 76 return false; 77 } 78 79 /* static */ 80 bool AnimationUtils::HasCurrentTransitions( 81 const Element* aElement, const PseudoStyleRequest& aPseudoRequest) { 82 MOZ_ASSERT(aElement); 83 84 EffectSet* effectSet = EffectSet::Get(aElement, aPseudoRequest); 85 if (!effectSet) { 86 return false; 87 } 88 89 for (const dom::KeyframeEffect* effect : *effectSet) { 90 // If |effect| is current, it must have an associated Animation 91 // so we don't need to null-check the result of GetAnimation(). 92 if (effect->IsCurrent() && effect->GetAnimation()->AsCSSTransition()) { 93 return true; 94 } 95 } 96 97 return false; 98 } 99 100 /*static*/ 101 std::pair<const Element*, PseudoStyleRequest> 102 AnimationUtils::GetElementPseudoPair(const Element* aElementOrPseudo) { 103 MOZ_ASSERT(aElementOrPseudo); 104 105 if (aElementOrPseudo->IsGeneratedContentContainerForBefore()) { 106 return {aElementOrPseudo->GetParent()->AsElement(), 107 PseudoStyleRequest::Before()}; 108 } 109 110 if (aElementOrPseudo->IsGeneratedContentContainerForAfter()) { 111 return {aElementOrPseudo->GetParent()->AsElement(), 112 PseudoStyleRequest::After()}; 113 } 114 115 if (aElementOrPseudo->IsGeneratedContentContainerForMarker()) { 116 return {aElementOrPseudo->GetParent()->AsElement(), 117 PseudoStyleRequest::Marker()}; 118 } 119 120 if (aElementOrPseudo->IsGeneratedContentContainerForBackdrop()) { 121 return {aElementOrPseudo->GetParent()->AsElement(), 122 PseudoStyleRequest::Backdrop()}; 123 } 124 125 const PseudoStyleType type = aElementOrPseudo->GetPseudoElementType(); 126 if (PseudoStyle::IsViewTransitionPseudoElement(type)) { 127 // Note: ::view-transition doesn't have a name, so we check if it has a name 128 // first. 129 nsAtom* name = 130 aElementOrPseudo->HasName() 131 ? aElementOrPseudo->GetParsedAttr(nsGkAtoms::name)->GetAtomValue() 132 : nullptr; 133 return {aElementOrPseudo->GetOwnerDocument()->GetRootElement(), 134 PseudoStyleRequest(type, name)}; 135 } 136 137 return {aElementOrPseudo, PseudoStyleRequest::NotPseudo()}; 138 } 139 140 } // namespace mozilla