зеркало из https://github.com/mozilla/pjs.git
Bug 512525 - Implement SVG Fragment Identifier parsing and animation hyperlinking - Part 1 infrastructure to support hyperlinking. r=dholbert
This commit is contained in:
Родитель
1333ad9b17
Коммит
9fff4c1440
|
@ -354,6 +354,23 @@ nsSMILTimedElement::GetStartTime() const
|
|||
: nsSMILTimeValue();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Hyperlinking support
|
||||
|
||||
nsSMILTimeValue
|
||||
nsSMILTimedElement::GetHyperlinkTime() const
|
||||
{
|
||||
nsSMILTimeValue hyperlinkTime; // Default ctor creates unresolved time
|
||||
|
||||
if (mElementState == STATE_ACTIVE) {
|
||||
hyperlinkTime = mCurrentInterval->Begin()->Time();
|
||||
} else if (!mBeginInstances.IsEmpty()) {
|
||||
hyperlinkTime = mBeginInstances[0]->Time();
|
||||
}
|
||||
|
||||
return hyperlinkTime;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsSMILTimedElement
|
||||
|
||||
|
@ -1492,7 +1509,8 @@ nsSMILTimedElement::FilterIntervals()
|
|||
// We can filter old intervals that:
|
||||
//
|
||||
// a) are not the previous interval; AND
|
||||
// b) are not in the middle of a dependency chain
|
||||
// b) are not in the middle of a dependency chain; AND
|
||||
// c) are not the first interval
|
||||
//
|
||||
// Condition (a) is necessary since the previous interval is used for applying
|
||||
// fill effects and updating the current interval.
|
||||
|
@ -1502,6 +1520,15 @@ nsSMILTimedElement::FilterIntervals()
|
|||
// intervals. Such chains are used to establish priorities within the
|
||||
// animation sandwich.
|
||||
//
|
||||
// Condition (c) is necessary to support hyperlinks that target animations
|
||||
// since in some cases the defined behavior is to seek the document back to
|
||||
// the first resolved begin time. Presumably the intention here is not
|
||||
// actually to use the first resolved begin time, the
|
||||
// _the_first_resolved_begin_time_that_produced_an_interval. That is,
|
||||
// if we have begin="-5s; -3s; 1s; 3s" with a duration on 1s, we should seek
|
||||
// to 1s. The spec doesn't say this but I'm pretty sure that is the intention.
|
||||
// It seems negative times were simply not considered.
|
||||
//
|
||||
// Although the above conditions allow us to safely filter intervals for most
|
||||
// scenarios they do not cover all cases and there will still be scenarios
|
||||
// that generate intervals indefinitely. In such a case we simply set
|
||||
|
@ -1514,7 +1541,8 @@ nsSMILTimedElement::FilterIntervals()
|
|||
for (PRUint32 i = 0; i < mOldIntervals.Length(); ++i)
|
||||
{
|
||||
nsSMILInterval* interval = mOldIntervals[i].get();
|
||||
if (i + 1 < mOldIntervals.Length() /*skip previous interval*/ &&
|
||||
if (i != 0 && /*skip first interval*/
|
||||
i + 1 < mOldIntervals.Length() && /*skip previous interval*/
|
||||
(i < threshold || !interval->IsDependencyChainLink())) {
|
||||
interval->Unlink(true /*filtered, not deleted*/);
|
||||
} else {
|
||||
|
@ -1584,6 +1612,7 @@ nsSMILTimedElement::FilterInstanceTimes(InstanceTimeList& aList)
|
|||
// There are a few instance times we should keep though, notably:
|
||||
// - the current interval begin time,
|
||||
// - the previous interval end time (see note in RemoveInstanceTimes)
|
||||
// - the first interval begin time (see note in FilterIntervals)
|
||||
nsTArray<const nsSMILInstanceTime *> timesToKeep;
|
||||
if (mCurrentInterval) {
|
||||
timesToKeep.AppendElement(mCurrentInterval->Begin());
|
||||
|
@ -1592,6 +1621,9 @@ nsSMILTimedElement::FilterInstanceTimes(InstanceTimeList& aList)
|
|||
if (prevInterval) {
|
||||
timesToKeep.AppendElement(prevInterval->End());
|
||||
}
|
||||
if (!mOldIntervals.IsEmpty()) {
|
||||
timesToKeep.AppendElement(mOldIntervals[0]->Begin());
|
||||
}
|
||||
RemoveBelowThreshold removeBelowThreshold(threshold, timesToKeep);
|
||||
RemoveInstanceTimes(aList, removeBelowThreshold);
|
||||
}
|
||||
|
|
|
@ -139,10 +139,29 @@ public:
|
|||
return mSimpleDur;
|
||||
}
|
||||
|
||||
/**
|
||||
* Methods for supporting hyperlinking
|
||||
*/
|
||||
|
||||
/**
|
||||
* Internal SMIL methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the time to seek the document to when this element is targetted by
|
||||
* a hyperlink.
|
||||
*
|
||||
* The behavior is defined here:
|
||||
* http://www.w3.org/TR/smil-animation/#HyperlinkSemantics
|
||||
*
|
||||
* It is very similar to GetStartTime() with the exception that when the
|
||||
* element is not active, the begin time of the *first* interval is returned.
|
||||
*
|
||||
* @return the time to seek the documen to in milliseconds or an unresolved
|
||||
* time if there is no resolved interval.
|
||||
*/
|
||||
nsSMILTimeValue GetHyperlinkTime() const;
|
||||
|
||||
/**
|
||||
* Adds an instance time object this element's list of instance times.
|
||||
* These instance times are used when creating intervals.
|
||||
|
|
|
@ -422,6 +422,34 @@ nsSVGAnimationElement::IsNodeOfType(PRUint32 aFlags) const
|
|||
return !(aFlags & ~(eCONTENT | eANIMATION));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// SVG utility methods
|
||||
|
||||
void
|
||||
nsSVGAnimationElement::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 nsSVGSVGElement::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 {
|
||||
BeginElement();
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Implementation helpers
|
||||
|
||||
|
|
|
@ -100,6 +100,9 @@ public:
|
|||
virtual nsSMILTimedElement& TimedElement();
|
||||
virtual nsSMILTimeContainer* GetTimeContainer();
|
||||
|
||||
// Utility methods for within SVG
|
||||
void ActivateByHyperlink();
|
||||
|
||||
protected:
|
||||
// nsSVGElement overrides
|
||||
bool IsEventName(nsIAtom* aName);
|
||||
|
|
Загрузка…
Ссылка в новой задаче