void SVGAnimationElement::ActivateByHyperlink() { FlushAnimations(); // The behavior for when the target is an animation element is defined in // SMIL Animation: // http://www.w3.org/TR/smil-animation/#HyperlinkSemantics nsSMILTimeValue seekTime = mTimedElement.GetHyperlinkTime(); if (seekTime.IsDefinite()) { nsSMILTimeContainer* timeContainer = GetTimeContainer(); if (timeContainer) { timeContainer->SetCurrentTime(seekTime.GetMillis()); AnimationNeedsResample(); // As with SVGSVGElement::SetCurrentTime, we need to trigger // a synchronous sample now. FlushAnimations(); } // else, silently fail. We mustn't be part of an SVG document fragment that // is attached to the document tree so there's nothing we can do here } else { ErrorResult rv; BeginElement(rv); } }
nsresult SVGAnimationElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName, const nsAttrValue* aValue, bool aNotify) { nsresult rv = SVGAnimationElementBase::AfterSetAttr(aNamespaceID, aName, aValue, aNotify); if (SVGTests::IsConditionalProcessingAttribute(aName)) { bool isDisabled = !SVGTests::PassesConditionalProcessingTests(); if (mTimedElement.SetIsDisabled(isDisabled)) { AnimationNeedsResample(); } } if (aNamespaceID != kNameSpaceID_XLink || aName != nsGkAtoms::href) return rv; if (!aValue) { mHrefTarget.Unlink(); AnimationTargetChanged(); } else if (IsInDoc()) { MOZ_ASSERT(aValue->Type() == nsAttrValue::eString, "Expected href attribute to be string type"); UpdateHrefTarget(this, aValue->GetStringValue()); } // else: we're not yet in a document -- we'll update the target on // next BindToTree call. return rv; }
bool SVGAnimationElement::ParseAttribute(int32_t aNamespaceID, nsIAtom* aAttribute, const nsAString& aValue, nsAttrValue& aResult) { if (aNamespaceID == kNameSpaceID_None) { // Deal with target-related attributes here if (aAttribute == nsGkAtoms::attributeName || aAttribute == nsGkAtoms::attributeType) { aResult.ParseAtom(aValue); AnimationNeedsResample(); return true; } nsresult rv = NS_ERROR_FAILURE; // First let the animation function try to parse it... bool foundMatch = AnimationFunction().SetAttr(aAttribute, aValue, aResult, &rv); // ... and if that didn't recognize the attribute, let the timed element // try to parse it. if (!foundMatch) { foundMatch = mTimedElement.SetAttr(aAttribute, aValue, aResult, this, &rv); } if (foundMatch) { AnimationNeedsResample(); if (NS_FAILED(rv)) { ReportAttributeParseFailure(OwnerDoc(), aAttribute, aValue); return false; } return true; } } return SVGAnimationElementBase::ParseAttribute(aNamespaceID, aAttribute, aValue, aResult); }
void SVGMPathElement::NotifyParentOfMpathChange(nsIContent* aParent) { if (aParent && aParent->IsSVG(nsGkAtoms::animateMotion)) { SVGAnimateMotionElement* animateMotionParent = static_cast<SVGAnimateMotionElement*>(aParent); animateMotionParent->MpathChanged(); AnimationNeedsResample(); } }
void SVGAnimationElement::EndElementAt(float offset, ErrorResult& rv) { // Make sure the timegraph is up-to-date FlushAnimations(); rv = mTimedElement.EndElementAt(offset); if (rv.Failed()) return; AnimationNeedsResample(); // Force synchronous sample FlushAnimations(); }
void SVGAnimationElement::UnbindFromTree(bool aDeep, bool aNullParent) { nsSMILAnimationController *controller = OwnerDoc()->GetAnimationController(); if (controller) { controller->UnregisterAnimationElement(this); } mHrefTarget.Unlink(); mTimedElement.DissolveReferences(); AnimationNeedsResample(); SVGAnimationElementBase::UnbindFromTree(aDeep, aNullParent); }
nsresult SVGAnimationElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent, nsIContent* aBindingParent, bool aCompileEventHandlers) { NS_ABORT_IF_FALSE(!mHrefTarget.get(), "Shouldn't have href-target yet " "(or it should've been cleared)"); nsresult rv = SVGAnimationElementBase::BindToTree(aDocument, aParent, aBindingParent, aCompileEventHandlers); NS_ENSURE_SUCCESS(rv,rv); // XXXdholbert is GetCtx (as a check for SVG parent) still needed here? if (!GetCtx()) { // No use proceeding. We don't have an SVG parent (yet) so we won't be able // to register ourselves etc. Maybe next time we'll have more luck. // (This sort of situation will arise a lot when trees are being constructed // piece by piece via script) return NS_OK; } // Add myself to the animation controller's master set of animation elements. if (aDocument) { nsSMILAnimationController *controller = aDocument->GetAnimationController(); if (controller) { controller->RegisterAnimationElement(this); } const nsAttrValue* href = mAttrsAndChildren.GetAttr(nsGkAtoms::href, kNameSpaceID_XLink); if (href) { nsAutoString hrefStr; href->ToString(hrefStr); // Pass in |aParent| instead of |this| -- first argument is only used // for a call to GetCurrentDoc(), and |this| might not have a current // document yet. UpdateHrefTarget(aParent, hrefStr); } mTimedElement.BindToTree(aParent); } AnimationNeedsResample(); return NS_OK; }
void SVGAnimationElement::BeginElementAt(float offset, ErrorResult& rv) { // Make sure the timegraph is up-to-date FlushAnimations(); // This will fail if we're not attached to a time container (SVG document // fragment). rv = mTimedElement.BeginElementAt(offset); if (rv.Failed()) return; AnimationNeedsResample(); // Force synchronous sample so that events resulting from this call arrive in // the expected order and we get an up-to-date paint. FlushAnimations(); }
nsresult SVGAnimationElement::UnsetAttr(int32_t aNamespaceID, nsIAtom* aAttribute, bool aNotify) { nsresult rv = SVGAnimationElementBase::UnsetAttr(aNamespaceID, aAttribute, aNotify); NS_ENSURE_SUCCESS(rv,rv); if (aNamespaceID == kNameSpaceID_None) { if (AnimationFunction().UnsetAttr(aAttribute) || mTimedElement.UnsetAttr(aAttribute)) { AnimationNeedsResample(); } } return NS_OK; }
void SVGAnimationElement::AnimationTargetChanged() { mTimedElement.HandleTargetElementChange(GetTargetElementContent()); AnimationNeedsResample(); }