зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1244586 part 1 - Add KeyframeEffect constructor in dom/webidl/KeyframeEffect.webidl. r=smaug,birtles
This commit is contained in:
Родитель
e54a74b405
Коммит
cc127029f8
|
@ -76,14 +76,24 @@ KeyframeEffectReadOnly::KeyframeEffectReadOnly(
|
|||
Element* aTarget,
|
||||
nsCSSPseudoElements::Type aPseudoType,
|
||||
const TimingParams& aTiming)
|
||||
: KeyframeEffectReadOnly(aDocument, aTarget, aPseudoType,
|
||||
new AnimationEffectTimingReadOnly(aTiming))
|
||||
{
|
||||
}
|
||||
|
||||
KeyframeEffectReadOnly::KeyframeEffectReadOnly(
|
||||
nsIDocument* aDocument,
|
||||
Element* aTarget,
|
||||
nsCSSPseudoElements::Type aPseudoType,
|
||||
AnimationEffectTimingReadOnly* aTiming)
|
||||
: AnimationEffectReadOnly(aDocument)
|
||||
, mTarget(aTarget)
|
||||
, mTiming(*aTiming)
|
||||
, mPseudoType(aPseudoType)
|
||||
, mInEffectOnLastAnimationTimingUpdate(false)
|
||||
{
|
||||
MOZ_ASSERT(aTiming);
|
||||
MOZ_ASSERT(aTarget, "null animation target is not yet supported");
|
||||
|
||||
mTiming = new AnimationEffectTimingReadOnly(aTiming);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
|
@ -595,6 +605,72 @@ KeyframeEffectReadOnly::~KeyframeEffectReadOnly()
|
|||
{
|
||||
}
|
||||
|
||||
template <class KeyframeEffectType>
|
||||
/* static */ already_AddRefed<KeyframeEffectType>
|
||||
KeyframeEffectReadOnly::ConstructKeyframeEffect(const GlobalObject& aGlobal,
|
||||
const Nullable<ElementOrCSSPseudoElement>& aTarget,
|
||||
JS::Handle<JSObject*> aFrames,
|
||||
const TimingParams& aTiming,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (aTarget.IsNull()) {
|
||||
// We don't support null targets yet.
|
||||
aRv.Throw(NS_ERROR_DOM_ANIM_NO_TARGET_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const ElementOrCSSPseudoElement& target = aTarget.Value();
|
||||
MOZ_ASSERT(target.IsElement() || target.IsCSSPseudoElement(),
|
||||
"Uninitialized target");
|
||||
|
||||
RefPtr<Element> targetElement;
|
||||
nsCSSPseudoElements::Type pseudoType =
|
||||
nsCSSPseudoElements::ePseudo_NotPseudoElement;
|
||||
if (target.IsElement()) {
|
||||
targetElement = &target.GetAsElement();
|
||||
} else {
|
||||
targetElement = target.GetAsCSSPseudoElement().ParentElement();
|
||||
pseudoType = target.GetAsCSSPseudoElement().GetType();
|
||||
}
|
||||
|
||||
if (!targetElement->GetComposedDoc()) {
|
||||
aRv.Throw(NS_ERROR_DOM_ANIM_TARGET_NOT_IN_DOC_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
InfallibleTArray<AnimationProperty> animationProperties;
|
||||
BuildAnimationPropertyList(aGlobal.Context(), targetElement, pseudoType,
|
||||
aFrames, animationProperties, aRv);
|
||||
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<KeyframeEffectType> effect =
|
||||
new KeyframeEffectType(targetElement->OwnerDoc(), targetElement,
|
||||
pseudoType, aTiming);
|
||||
effect->mProperties = Move(animationProperties);
|
||||
return effect.forget();
|
||||
}
|
||||
|
||||
// Explicit instantiations to avoid linker errors.
|
||||
|
||||
template
|
||||
already_AddRefed<KeyframeEffectReadOnly>
|
||||
KeyframeEffectReadOnly::ConstructKeyframeEffect<>(const GlobalObject& aGlobal,
|
||||
const Nullable<ElementOrCSSPseudoElement>& aTarget,
|
||||
JS::Handle<JSObject*> aFrames,
|
||||
const TimingParams& aTiming,
|
||||
ErrorResult& aRv);
|
||||
|
||||
template
|
||||
already_AddRefed<KeyframeEffect>
|
||||
KeyframeEffectReadOnly::ConstructKeyframeEffect<>(const GlobalObject& aGlobal,
|
||||
const Nullable<ElementOrCSSPseudoElement>& aTarget,
|
||||
JS::Handle<JSObject*> aFrames,
|
||||
const TimingParams& aTiming,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void
|
||||
KeyframeEffectReadOnly::ResetIsRunningOnCompositor()
|
||||
{
|
||||
|
@ -1635,55 +1711,6 @@ KeyframeEffectReadOnly::BuildAnimationPropertyList(
|
|||
}
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<KeyframeEffectReadOnly>
|
||||
KeyframeEffectReadOnly::Constructor(
|
||||
const GlobalObject& aGlobal,
|
||||
const Nullable<ElementOrCSSPseudoElement>& aTarget,
|
||||
JS::Handle<JSObject*> aFrames,
|
||||
const TimingParams& aTiming,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (aTarget.IsNull()) {
|
||||
// We don't support null targets yet.
|
||||
aRv.Throw(NS_ERROR_DOM_ANIM_NO_TARGET_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const ElementOrCSSPseudoElement& target = aTarget.Value();
|
||||
MOZ_ASSERT(target.IsElement() || target.IsCSSPseudoElement(),
|
||||
"Uninitialized target");
|
||||
|
||||
RefPtr<Element> targetElement;
|
||||
nsCSSPseudoElements::Type pseudoType =
|
||||
nsCSSPseudoElements::ePseudo_NotPseudoElement;
|
||||
if (target.IsElement()) {
|
||||
targetElement = &target.GetAsElement();
|
||||
} else {
|
||||
targetElement = target.GetAsCSSPseudoElement().ParentElement();
|
||||
pseudoType = target.GetAsCSSPseudoElement().GetType();
|
||||
}
|
||||
|
||||
if (!targetElement->GetCurrentDoc()) {
|
||||
// Bug 1245748: We don't support targets that are not in a document yet.
|
||||
aRv.Throw(NS_ERROR_DOM_ANIM_TARGET_NOT_IN_DOC_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
InfallibleTArray<AnimationProperty> animationProperties;
|
||||
BuildAnimationPropertyList(aGlobal.Context(), targetElement, pseudoType,
|
||||
aFrames, animationProperties, aRv);
|
||||
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<KeyframeEffectReadOnly> effect =
|
||||
new KeyframeEffectReadOnly(targetElement->OwnerDoc(), targetElement,
|
||||
pseudoType, aTiming);
|
||||
effect->mProperties = Move(animationProperties);
|
||||
return effect.forget();
|
||||
}
|
||||
|
||||
void
|
||||
KeyframeEffectReadOnly::GetTarget(
|
||||
Nullable<OwningElementOrCSSPseudoElement>& aRv) const
|
||||
|
@ -2091,6 +2118,21 @@ KeyframeEffectReadOnly::ShouldBlockCompositorAnimations(const nsIFrame*
|
|||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
//
|
||||
// KeyframeEffect
|
||||
//
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
KeyframeEffect::KeyframeEffect(nsIDocument* aDocument,
|
||||
Element* aTarget,
|
||||
nsCSSPseudoElements::Type aPseudoType,
|
||||
const TimingParams& aTiming)
|
||||
: KeyframeEffectReadOnly(aDocument, aTarget, aPseudoType,
|
||||
new AnimationEffectTiming(aTiming))
|
||||
{
|
||||
}
|
||||
|
||||
JSObject*
|
||||
KeyframeEffect::WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto)
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "mozilla/StyleAnimationValue.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/dom/AnimationEffectReadOnly.h"
|
||||
#include "mozilla/dom/AnimationEffectTiming.h"
|
||||
#include "mozilla/dom/AnimationEffectTimingReadOnly.h" // TimingParams
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/KeyframeBinding.h"
|
||||
|
@ -195,20 +196,11 @@ public:
|
|||
const UnrestrictedDoubleOrKeyframeEffectOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
return Constructor(aGlobal, aTarget, aFrames,
|
||||
TimingParams::FromOptionsUnion(aOptions, aTarget),
|
||||
aRv);
|
||||
return ConstructKeyframeEffect<KeyframeEffectReadOnly>(
|
||||
aGlobal, aTarget, aFrames,
|
||||
TimingParams::FromOptionsUnion(aOptions, aTarget), aRv);
|
||||
}
|
||||
|
||||
// More generalized version for Animatable.animate.
|
||||
// Not exposed to content.
|
||||
static already_AddRefed<KeyframeEffectReadOnly>
|
||||
Constructor(const GlobalObject& aGlobal,
|
||||
const Nullable<ElementOrCSSPseudoElement>& aTarget,
|
||||
JS::Handle<JSObject*> aFrames,
|
||||
const TimingParams& aTiming,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void GetTarget(Nullable<OwningElementOrCSSPseudoElement>& aRv) const;
|
||||
void GetFrames(JSContext*& aCx,
|
||||
nsTArray<JSObject*>& aResult,
|
||||
|
@ -328,7 +320,21 @@ public:
|
|||
inline AnimationCollection* GetCollection() const;
|
||||
|
||||
protected:
|
||||
KeyframeEffectReadOnly(nsIDocument* aDocument,
|
||||
Element* aTarget,
|
||||
nsCSSPseudoElements::Type aPseudoType,
|
||||
AnimationEffectTimingReadOnly* aTiming);
|
||||
|
||||
virtual ~KeyframeEffectReadOnly();
|
||||
|
||||
template<typename KeyframeEffectType>
|
||||
static already_AddRefed<KeyframeEffectType>
|
||||
ConstructKeyframeEffect(const GlobalObject& aGlobal,
|
||||
const Nullable<ElementOrCSSPseudoElement>& aTarget,
|
||||
JS::Handle<JSObject*> aFrames,
|
||||
const TimingParams& aTiming,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void ResetIsRunningOnCompositor();
|
||||
|
||||
// This effect is registered with its target element so long as:
|
||||
|
@ -390,11 +396,35 @@ public:
|
|||
KeyframeEffect(nsIDocument* aDocument,
|
||||
Element* aTarget,
|
||||
nsCSSPseudoElements::Type aPseudoType,
|
||||
const TimingParams& aTiming)
|
||||
: KeyframeEffectReadOnly(aDocument, aTarget, aPseudoType, aTiming) { }
|
||||
const TimingParams& aTiming);
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
static already_AddRefed<KeyframeEffect>
|
||||
Constructor(const GlobalObject& aGlobal,
|
||||
const Nullable<ElementOrCSSPseudoElement>& aTarget,
|
||||
JS::Handle<JSObject*> aFrames,
|
||||
const UnrestrictedDoubleOrKeyframeEffectOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
return ConstructKeyframeEffect<KeyframeEffect>(
|
||||
aGlobal, aTarget, aFrames,
|
||||
TimingParams::FromOptionsUnion(aOptions, aTarget), aRv);
|
||||
}
|
||||
|
||||
// More generalized version for Animatable.animate.
|
||||
// Not exposed to content.
|
||||
static already_AddRefed<KeyframeEffect>
|
||||
inline Constructor(const GlobalObject& aGlobal,
|
||||
const Nullable<ElementOrCSSPseudoElement>& aTarget,
|
||||
JS::Handle<JSObject*> aFrames,
|
||||
const TimingParams& aTiming,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
return ConstructKeyframeEffect<KeyframeEffect>(aGlobal, aTarget, aFrames,
|
||||
aTiming, aRv);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -3337,9 +3337,8 @@ Element::Animate(JSContext* aContext,
|
|||
|
||||
Nullable<ElementOrCSSPseudoElement> target;
|
||||
target.SetValue().SetAsElement() = this;
|
||||
// Bug 1211783: Use KeyframeEffect here (instead of KeyframeEffectReadOnly)
|
||||
RefPtr<KeyframeEffectReadOnly> effect =
|
||||
KeyframeEffectReadOnly::Constructor(global, target, frames,
|
||||
RefPtr<KeyframeEffect> effect =
|
||||
KeyframeEffect::Constructor(global, target, frames,
|
||||
TimingParams::FromOptionsUnion(aOptions, target), aError);
|
||||
if (aError.Failed()) {
|
||||
return nullptr;
|
||||
|
|
|
@ -46,10 +46,9 @@ interface KeyframeEffectReadOnly : AnimationEffectReadOnly {
|
|||
};
|
||||
|
||||
|
||||
// Bug 1211783 Implement KeyframeEffect constructor
|
||||
// [Constructor (Animatable? target,
|
||||
// object? frames,
|
||||
// optional (unrestricted double or KeyframeEffectOptions) options)]
|
||||
[Constructor ((Element or CSSPseudoElement)? target,
|
||||
object? frames,
|
||||
optional (unrestricted double or KeyframeEffectOptions) options)]
|
||||
interface KeyframeEffect : KeyframeEffectReadOnly {
|
||||
// Bug 1067769 - Allow setting KeyframeEffect.target
|
||||
// inherit attribute Animatable? target;
|
||||
|
|
|
@ -629,6 +629,23 @@ gKeyframeEffectOptionTests.forEach(function(stest) {
|
|||
}, "a KeyframeEffectReadOnly constructed by " + stest.desc);
|
||||
});
|
||||
|
||||
test(function(t) {
|
||||
var effect = new KeyframeEffect(target,
|
||||
{left: ["10px", "20px"]});
|
||||
|
||||
assert_class_string(effect, "KeyframeEffect");
|
||||
assert_class_string(effect.timing, "AnimationEffectTiming");
|
||||
}, "KeyframeEffect constructor creates an AnimationEffectTiming timing object");
|
||||
|
||||
test(function(t) {
|
||||
var test_error = { name: "test" };
|
||||
|
||||
assert_throws(test_error, function() {
|
||||
new KeyframeEffect(target, { get left() { throw test_error }})
|
||||
});
|
||||
}, "KeyframeEffect constructor propagates exceptions generated by accessing"
|
||||
+ " the options object");
|
||||
|
||||
done();
|
||||
</script>
|
||||
</body>
|
||||
|
|
Загрузка…
Ссылка в новой задаче