Bug 1067769 - Part 8: Add ConvertTarget function. r=birtles draft
authorBoris Chiou <boris.chiou@gmail.com>
Thu, 28 Apr 2016 23:22:43 +0800
changeset 357394 d1a8fe2d8fe89e4ffdb79844ab5581a9af3b2ce5
parent 357393 b938dbc00c918861d4141128fad8e30f61668e40
child 357395 881aa13d79ccc75872a6cc48d0a1da71cfdff2ae
push id16759
push userbchiou@mozilla.com
push dateThu, 28 Apr 2016 15:27:13 +0000
reviewersbirtles
bugs1067769
milestone49.0a1
Bug 1067769 - Part 8: Add ConvertTarget function. r=birtles Use ConvertTarget() to convert Nullabe<ElementOrCSSPseudoElement> into Maybe<OwningAnimationTarget>, so SetTarget() can use it as well. The return type of ConvertTarget is not Maybe<NonOwningAnimationTarget> because we need to compare the return type with KeyframeEffectReadOnly::mTarget, so using the same type would be easier to implement. MozReview-Commit-ID: GskbydOMoo0
dom/animation/AnimationTarget.h
dom/animation/KeyframeEffect.cpp
--- a/dom/animation/AnimationTarget.h
+++ b/dom/animation/AnimationTarget.h
@@ -18,16 +18,19 @@ namespace dom {
 class Element;
 } // namespace dom
 
 struct OwningAnimationTarget
 {
   OwningAnimationTarget(dom::Element* aElement, CSSPseudoElementType aType)
     : mElement(aElement), mPseudoType(aType) { }
 
+  explicit OwningAnimationTarget(dom::Element* aElement)
+    : mElement(aElement) { }
+
   // mElement represents the parent element of a pseudo-element, not the
   // generated content element.
   RefPtr<dom::Element> mElement;
   CSSPseudoElementType mPseudoType = CSSPseudoElementType::NotPseudo;
 };
 
 struct NonOwningAnimationTarget
 {
--- a/dom/animation/KeyframeEffect.cpp
+++ b/dom/animation/KeyframeEffect.cpp
@@ -714,16 +714,39 @@ KeyframeEffectReadOnly::SetIsRunningOnCo
     }
   }
 }
 
 KeyframeEffectReadOnly::~KeyframeEffectReadOnly()
 {
 }
 
+static Maybe<OwningAnimationTarget>
+ConvertTarget(const Nullable<ElementOrCSSPseudoElement>& aTarget)
+{
+  // Return value optimization.
+  Maybe<OwningAnimationTarget> result;
+
+  if (aTarget.IsNull()) {
+    return result;
+  }
+
+  const ElementOrCSSPseudoElement& target = aTarget.Value();
+  MOZ_ASSERT(target.IsElement() || target.IsCSSPseudoElement(),
+             "Uninitialized target");
+
+  if (target.IsElement()) {
+    result.emplace(&target.GetAsElement());
+  } else {
+    RefPtr<Element> elem = target.GetAsCSSPseudoElement().ParentElement();
+    result.emplace(elem, target.GetAsCSSPseudoElement().GetType());
+  }
+  return result;
+}
+
 template <class KeyframeEffectType, class OptionsType>
 /* static */ already_AddRefed<KeyframeEffectType>
 KeyframeEffectReadOnly::ConstructKeyframeEffect(
     const GlobalObject& aGlobal,
     const Nullable<ElementOrCSSPseudoElement>& aTarget,
     JS::Handle<JSObject*> aFrames,
     const OptionsType& aOptions,
     ErrorResult& aRv)
@@ -735,32 +758,24 @@ KeyframeEffectReadOnly::ConstructKeyfram
   }
 
   TimingParams timingParams =
     TimingParams::FromOptionsUnion(aOptions, doc, aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
-  RefPtr<Element> targetElement;
-  CSSPseudoElementType pseudoType = CSSPseudoElementType::NotPseudo;
-  if (!aTarget.IsNull()) {
-    const ElementOrCSSPseudoElement& target = aTarget.Value();
-    MOZ_ASSERT(target.IsElement() || target.IsCSSPseudoElement(),
-               "Uninitialized target");
-    if (target.IsElement()) {
-      targetElement = &target.GetAsElement();
-    } else {
-      targetElement = target.GetAsCSSPseudoElement().ParentElement();
-      pseudoType = target.GetAsCSSPseudoElement().GetType();
-    }
-  }
+  Maybe<OwningAnimationTarget> target = ConvertTarget(aTarget);
+  RefPtr<KeyframeEffectType> effect =
+    new KeyframeEffectType(doc,
+                           target ? target->mElement.get() : nullptr,
+                           target ? target->mPseudoType
+                                  : CSSPseudoElementType::NotPseudo,
+                           timingParams);
 
-  RefPtr<KeyframeEffectType> effect =
-    new KeyframeEffectType(doc, targetElement, pseudoType, timingParams);
   effect->SetFrames(aGlobal.Context(), aFrames, aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
   return effect.forget();
 }