Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #ifndef NS_SMILTIMEDELEMENT_H_ |
michael@0 | 7 | #define NS_SMILTIMEDELEMENT_H_ |
michael@0 | 8 | |
michael@0 | 9 | #include "nsSMILInterval.h" |
michael@0 | 10 | #include "nsSMILInstanceTime.h" |
michael@0 | 11 | #include "nsSMILMilestone.h" |
michael@0 | 12 | #include "nsSMILTimeValueSpec.h" |
michael@0 | 13 | #include "nsSMILRepeatCount.h" |
michael@0 | 14 | #include "nsSMILTypes.h" |
michael@0 | 15 | #include "nsTArray.h" |
michael@0 | 16 | #include "nsTHashtable.h" |
michael@0 | 17 | #include "nsHashKeys.h" |
michael@0 | 18 | #include "nsAutoPtr.h" |
michael@0 | 19 | #include "nsAttrValue.h" |
michael@0 | 20 | |
michael@0 | 21 | class nsSMILAnimationFunction; |
michael@0 | 22 | class nsSMILTimeContainer; |
michael@0 | 23 | class nsSMILTimeValue; |
michael@0 | 24 | class nsIAtom; |
michael@0 | 25 | |
michael@0 | 26 | namespace mozilla { |
michael@0 | 27 | namespace dom { |
michael@0 | 28 | class SVGAnimationElement; |
michael@0 | 29 | } |
michael@0 | 30 | } |
michael@0 | 31 | |
michael@0 | 32 | //---------------------------------------------------------------------- |
michael@0 | 33 | // nsSMILTimedElement |
michael@0 | 34 | |
michael@0 | 35 | class nsSMILTimedElement |
michael@0 | 36 | { |
michael@0 | 37 | public: |
michael@0 | 38 | nsSMILTimedElement(); |
michael@0 | 39 | ~nsSMILTimedElement(); |
michael@0 | 40 | |
michael@0 | 41 | typedef mozilla::dom::Element Element; |
michael@0 | 42 | |
michael@0 | 43 | /* |
michael@0 | 44 | * Sets the owning animation element which this class uses to convert between |
michael@0 | 45 | * container times and to register timebase elements. |
michael@0 | 46 | */ |
michael@0 | 47 | void SetAnimationElement(mozilla::dom::SVGAnimationElement* aElement); |
michael@0 | 48 | |
michael@0 | 49 | /* |
michael@0 | 50 | * Returns the time container with which this timed element is associated or |
michael@0 | 51 | * nullptr if it is not associated with a time container. |
michael@0 | 52 | */ |
michael@0 | 53 | nsSMILTimeContainer* GetTimeContainer(); |
michael@0 | 54 | |
michael@0 | 55 | /* |
michael@0 | 56 | * Returns the element targeted by the animation element. Needed for |
michael@0 | 57 | * registering event listeners against the appropriate element. |
michael@0 | 58 | */ |
michael@0 | 59 | mozilla::dom::Element* GetTargetElement(); |
michael@0 | 60 | |
michael@0 | 61 | /** |
michael@0 | 62 | * Methods for supporting the nsIDOMElementTimeControl interface. |
michael@0 | 63 | */ |
michael@0 | 64 | |
michael@0 | 65 | /* |
michael@0 | 66 | * Adds a new begin instance time at the current container time plus or minus |
michael@0 | 67 | * the specified offset. |
michael@0 | 68 | * |
michael@0 | 69 | * @param aOffsetSeconds A real number specifying the number of seconds to add |
michael@0 | 70 | * to the current container time. |
michael@0 | 71 | * @return NS_OK if the operation succeeeded, or an error code otherwise. |
michael@0 | 72 | */ |
michael@0 | 73 | nsresult BeginElementAt(double aOffsetSeconds); |
michael@0 | 74 | |
michael@0 | 75 | /* |
michael@0 | 76 | * Adds a new end instance time at the current container time plus or minus |
michael@0 | 77 | * the specified offset. |
michael@0 | 78 | * |
michael@0 | 79 | * @param aOffsetSeconds A real number specifying the number of seconds to add |
michael@0 | 80 | * to the current container time. |
michael@0 | 81 | * @return NS_OK if the operation succeeeded, or an error code otherwise. |
michael@0 | 82 | */ |
michael@0 | 83 | nsresult EndElementAt(double aOffsetSeconds); |
michael@0 | 84 | |
michael@0 | 85 | /** |
michael@0 | 86 | * Methods for supporting the nsSVGAnimationElement interface. |
michael@0 | 87 | */ |
michael@0 | 88 | |
michael@0 | 89 | /** |
michael@0 | 90 | * According to SVG 1.1 SE this returns |
michael@0 | 91 | * |
michael@0 | 92 | * the begin time, in seconds, for this animation element's current |
michael@0 | 93 | * interval, if it exists, regardless of whether the interval has begun yet. |
michael@0 | 94 | * |
michael@0 | 95 | * @return the start time as defined above in milliseconds or an unresolved |
michael@0 | 96 | * time if there is no current interval. |
michael@0 | 97 | */ |
michael@0 | 98 | nsSMILTimeValue GetStartTime() const; |
michael@0 | 99 | |
michael@0 | 100 | /** |
michael@0 | 101 | * Returns the simple duration of this element. |
michael@0 | 102 | * |
michael@0 | 103 | * @return the simple duration in milliseconds or INDEFINITE. |
michael@0 | 104 | */ |
michael@0 | 105 | nsSMILTimeValue GetSimpleDuration() const |
michael@0 | 106 | { |
michael@0 | 107 | return mSimpleDur; |
michael@0 | 108 | } |
michael@0 | 109 | |
michael@0 | 110 | /** |
michael@0 | 111 | * Methods for supporting hyperlinking |
michael@0 | 112 | */ |
michael@0 | 113 | |
michael@0 | 114 | /** |
michael@0 | 115 | * Internal SMIL methods |
michael@0 | 116 | */ |
michael@0 | 117 | |
michael@0 | 118 | /** |
michael@0 | 119 | * Returns the time to seek the document to when this element is targetted by |
michael@0 | 120 | * a hyperlink. |
michael@0 | 121 | * |
michael@0 | 122 | * The behavior is defined here: |
michael@0 | 123 | * http://www.w3.org/TR/smil-animation/#HyperlinkSemantics |
michael@0 | 124 | * |
michael@0 | 125 | * It is very similar to GetStartTime() with the exception that when the |
michael@0 | 126 | * element is not active, the begin time of the *first* interval is returned. |
michael@0 | 127 | * |
michael@0 | 128 | * @return the time to seek the documen to in milliseconds or an unresolved |
michael@0 | 129 | * time if there is no resolved interval. |
michael@0 | 130 | */ |
michael@0 | 131 | nsSMILTimeValue GetHyperlinkTime() const; |
michael@0 | 132 | |
michael@0 | 133 | /** |
michael@0 | 134 | * Adds an instance time object this element's list of instance times. |
michael@0 | 135 | * These instance times are used when creating intervals. |
michael@0 | 136 | * |
michael@0 | 137 | * This method is typically called by an nsSMILTimeValueSpec. |
michael@0 | 138 | * |
michael@0 | 139 | * @param aInstanceTime The time to add, expressed in container time. |
michael@0 | 140 | * @param aIsBegin true if the time to be added represents a begin |
michael@0 | 141 | * time or false if it represents an end time. |
michael@0 | 142 | */ |
michael@0 | 143 | void AddInstanceTime(nsSMILInstanceTime* aInstanceTime, bool aIsBegin); |
michael@0 | 144 | |
michael@0 | 145 | /** |
michael@0 | 146 | * Requests this element update the given instance time. |
michael@0 | 147 | * |
michael@0 | 148 | * This method is typically called by a child nsSMILTimeValueSpec. |
michael@0 | 149 | * |
michael@0 | 150 | * @param aInstanceTime The instance time to update. |
michael@0 | 151 | * @param aUpdatedTime The time to update aInstanceTime with. |
michael@0 | 152 | * @param aDependentTime The instance time upon which aInstanceTime should be |
michael@0 | 153 | * based. |
michael@0 | 154 | * @param aIsBegin true if the time to be updated represents a begin |
michael@0 | 155 | * instance time or false if it represents an end |
michael@0 | 156 | * instance time. |
michael@0 | 157 | */ |
michael@0 | 158 | void UpdateInstanceTime(nsSMILInstanceTime* aInstanceTime, |
michael@0 | 159 | nsSMILTimeValue& aUpdatedTime, |
michael@0 | 160 | bool aIsBegin); |
michael@0 | 161 | |
michael@0 | 162 | /** |
michael@0 | 163 | * Removes an instance time object from this element's list of instance times. |
michael@0 | 164 | * |
michael@0 | 165 | * This method is typically called by a child nsSMILTimeValueSpec. |
michael@0 | 166 | * |
michael@0 | 167 | * @param aInstanceTime The instance time to remove. |
michael@0 | 168 | * @param aIsBegin true if the time to be removed represents a begin |
michael@0 | 169 | * time or false if it represents an end time. |
michael@0 | 170 | */ |
michael@0 | 171 | void RemoveInstanceTime(nsSMILInstanceTime* aInstanceTime, bool aIsBegin); |
michael@0 | 172 | |
michael@0 | 173 | /** |
michael@0 | 174 | * Removes all the instance times associated with the given |
michael@0 | 175 | * nsSMILTimeValueSpec object. Used when an ID assignment changes and hence |
michael@0 | 176 | * all the previously associated instance times become invalid. |
michael@0 | 177 | * |
michael@0 | 178 | * @param aSpec The nsSMILTimeValueSpec object whose created |
michael@0 | 179 | * nsSMILInstanceTime's should be removed. |
michael@0 | 180 | * @param aIsBegin true if the times to be removed represent begin |
michael@0 | 181 | * times or false if they are end times. |
michael@0 | 182 | */ |
michael@0 | 183 | void RemoveInstanceTimesForCreator(const nsSMILTimeValueSpec* aSpec, |
michael@0 | 184 | bool aIsBegin); |
michael@0 | 185 | |
michael@0 | 186 | /** |
michael@0 | 187 | * Sets the object that will be called by this timed element each time it is |
michael@0 | 188 | * sampled. |
michael@0 | 189 | * |
michael@0 | 190 | * In Schmitz's model it is possible to associate several time clients with |
michael@0 | 191 | * a timed element but for now we only allow one. |
michael@0 | 192 | * |
michael@0 | 193 | * @param aClient The time client to associate. Any previous time client |
michael@0 | 194 | * will be disassociated and no longer sampled. Setting this |
michael@0 | 195 | * to nullptr will simply disassociate the previous client, if |
michael@0 | 196 | * any. |
michael@0 | 197 | */ |
michael@0 | 198 | void SetTimeClient(nsSMILAnimationFunction* aClient); |
michael@0 | 199 | |
michael@0 | 200 | /** |
michael@0 | 201 | * Samples the object at the given container time. Timing intervals are |
michael@0 | 202 | * updated and if this element is active at the given time the associated time |
michael@0 | 203 | * client will be sampled with the appropriate simple time. |
michael@0 | 204 | * |
michael@0 | 205 | * @param aContainerTime The container time at which to sample. |
michael@0 | 206 | */ |
michael@0 | 207 | void SampleAt(nsSMILTime aContainerTime); |
michael@0 | 208 | |
michael@0 | 209 | /** |
michael@0 | 210 | * Performs a special sample for the end of an interval. Such a sample should |
michael@0 | 211 | * only advance the timed element (and any dependent elements) to the waiting |
michael@0 | 212 | * or postactive state. It should not cause a transition to the active state. |
michael@0 | 213 | * Transition to the active state is only performed on a regular SampleAt. |
michael@0 | 214 | * |
michael@0 | 215 | * This allows all interval ends at a given time to be processed first and |
michael@0 | 216 | * hence the new interval can be established based on full information of the |
michael@0 | 217 | * available instance times. |
michael@0 | 218 | * |
michael@0 | 219 | * @param aContainerTime The container time at which to sample. |
michael@0 | 220 | */ |
michael@0 | 221 | void SampleEndAt(nsSMILTime aContainerTime); |
michael@0 | 222 | |
michael@0 | 223 | /** |
michael@0 | 224 | * Informs the timed element that its time container has changed time |
michael@0 | 225 | * relative to document time. The timed element therefore needs to update its |
michael@0 | 226 | * dependent elements (which may belong to a different time container) so they |
michael@0 | 227 | * can re-resolve their times. |
michael@0 | 228 | */ |
michael@0 | 229 | void HandleContainerTimeChange(); |
michael@0 | 230 | |
michael@0 | 231 | /** |
michael@0 | 232 | * Resets this timed element's accumulated times and intervals back to start |
michael@0 | 233 | * up state. |
michael@0 | 234 | * |
michael@0 | 235 | * This is used for backwards seeking where rather than accumulating |
michael@0 | 236 | * historical timing state and winding it back, we reset the element and seek |
michael@0 | 237 | * forwards. |
michael@0 | 238 | */ |
michael@0 | 239 | void Rewind(); |
michael@0 | 240 | |
michael@0 | 241 | /** |
michael@0 | 242 | * Attempts to set an attribute on this timed element. |
michael@0 | 243 | * |
michael@0 | 244 | * @param aAttribute The name of the attribute to set. The namespace of this |
michael@0 | 245 | * attribute is not specified as it is checked by the host |
michael@0 | 246 | * element. Only attributes in the namespace defined for |
michael@0 | 247 | * SMIL attributes in the host language are passed to the |
michael@0 | 248 | * timed element. |
michael@0 | 249 | * @param aValue The attribute value. |
michael@0 | 250 | * @param aResult The nsAttrValue object that may be used for storing the |
michael@0 | 251 | * parsed result. |
michael@0 | 252 | * @param aContextNode The element to use for context when resolving |
michael@0 | 253 | * references to other elements. |
michael@0 | 254 | * @param[out] aParseResult The result of parsing the attribute. Will be set |
michael@0 | 255 | * to NS_OK if parsing is successful. |
michael@0 | 256 | * |
michael@0 | 257 | * @return true if the given attribute is a timing attribute, false |
michael@0 | 258 | * otherwise. |
michael@0 | 259 | */ |
michael@0 | 260 | bool SetAttr(nsIAtom* aAttribute, const nsAString& aValue, |
michael@0 | 261 | nsAttrValue& aResult, Element* aContextNode, |
michael@0 | 262 | nsresult* aParseResult = nullptr); |
michael@0 | 263 | |
michael@0 | 264 | /** |
michael@0 | 265 | * Attempts to unset an attribute on this timed element. |
michael@0 | 266 | * |
michael@0 | 267 | * @param aAttribute The name of the attribute to set. As with SetAttr the |
michael@0 | 268 | * namespace of the attribute is not specified (see |
michael@0 | 269 | * SetAttr). |
michael@0 | 270 | * |
michael@0 | 271 | * @return true if the given attribute is a timing attribute, false |
michael@0 | 272 | * otherwise. |
michael@0 | 273 | */ |
michael@0 | 274 | bool UnsetAttr(nsIAtom* aAttribute); |
michael@0 | 275 | |
michael@0 | 276 | /** |
michael@0 | 277 | * Adds a syncbase dependency to the list of dependents that will be notified |
michael@0 | 278 | * when this timed element creates, deletes, or updates its current interval. |
michael@0 | 279 | * |
michael@0 | 280 | * @param aDependent The nsSMILTimeValueSpec object to notify. A raw pointer |
michael@0 | 281 | * to this object will be stored. Therefore it is necessary |
michael@0 | 282 | * for the object to be explicitly unregistered (with |
michael@0 | 283 | * RemoveDependent) when it is destroyed. |
michael@0 | 284 | */ |
michael@0 | 285 | void AddDependent(nsSMILTimeValueSpec& aDependent); |
michael@0 | 286 | |
michael@0 | 287 | /** |
michael@0 | 288 | * Removes a syncbase dependency from the list of dependents that are notified |
michael@0 | 289 | * when the current interval is modified. |
michael@0 | 290 | * |
michael@0 | 291 | * @param aDependent The nsSMILTimeValueSpec object to unregister. |
michael@0 | 292 | */ |
michael@0 | 293 | void RemoveDependent(nsSMILTimeValueSpec& aDependent); |
michael@0 | 294 | |
michael@0 | 295 | /** |
michael@0 | 296 | * Determines if this timed element is dependent on the given timed element's |
michael@0 | 297 | * begin time for the interval currently in effect. Whilst the element is in |
michael@0 | 298 | * the active state this is the current interval and in the postactive or |
michael@0 | 299 | * waiting state this is the previous interval if one exists. In all other |
michael@0 | 300 | * cases the element is not considered a time dependent of any other element. |
michael@0 | 301 | * |
michael@0 | 302 | * @param aOther The potential syncbase element. |
michael@0 | 303 | * @return true if this timed element's begin time for the currently |
michael@0 | 304 | * effective interval is directly or indirectly derived from aOther, false |
michael@0 | 305 | * otherwise. |
michael@0 | 306 | */ |
michael@0 | 307 | bool IsTimeDependent(const nsSMILTimedElement& aOther) const; |
michael@0 | 308 | |
michael@0 | 309 | /** |
michael@0 | 310 | * Called when the timed element has been bound to the document so that |
michael@0 | 311 | * references from this timed element to other elements can be resolved. |
michael@0 | 312 | * |
michael@0 | 313 | * @param aContextNode The node which provides the necessary context for |
michael@0 | 314 | * resolving references. This is typically the element in |
michael@0 | 315 | * the host language that owns this timed element. Should |
michael@0 | 316 | * not be null. |
michael@0 | 317 | */ |
michael@0 | 318 | void BindToTree(nsIContent* aContextNode); |
michael@0 | 319 | |
michael@0 | 320 | /** |
michael@0 | 321 | * Called when the target of the animation has changed so that event |
michael@0 | 322 | * registrations can be updated. |
michael@0 | 323 | */ |
michael@0 | 324 | void HandleTargetElementChange(mozilla::dom::Element* aNewTarget); |
michael@0 | 325 | |
michael@0 | 326 | /** |
michael@0 | 327 | * Called when the timed element has been removed from a document so that |
michael@0 | 328 | * references to other elements can be broken. |
michael@0 | 329 | */ |
michael@0 | 330 | void DissolveReferences() { Unlink(); } |
michael@0 | 331 | |
michael@0 | 332 | // Cycle collection |
michael@0 | 333 | void Traverse(nsCycleCollectionTraversalCallback* aCallback); |
michael@0 | 334 | void Unlink(); |
michael@0 | 335 | |
michael@0 | 336 | typedef bool (*RemovalTestFunction)(nsSMILInstanceTime* aInstance); |
michael@0 | 337 | |
michael@0 | 338 | protected: |
michael@0 | 339 | // Typedefs |
michael@0 | 340 | typedef nsTArray<nsAutoPtr<nsSMILTimeValueSpec> > TimeValueSpecList; |
michael@0 | 341 | typedef nsTArray<nsRefPtr<nsSMILInstanceTime> > InstanceTimeList; |
michael@0 | 342 | typedef nsTArray<nsAutoPtr<nsSMILInterval> > IntervalList; |
michael@0 | 343 | typedef nsPtrHashKey<nsSMILTimeValueSpec> TimeValueSpecPtrKey; |
michael@0 | 344 | typedef nsTHashtable<TimeValueSpecPtrKey> TimeValueSpecHashSet; |
michael@0 | 345 | |
michael@0 | 346 | // Helper classes |
michael@0 | 347 | class InstanceTimeComparator { |
michael@0 | 348 | public: |
michael@0 | 349 | bool Equals(const nsSMILInstanceTime* aElem1, |
michael@0 | 350 | const nsSMILInstanceTime* aElem2) const; |
michael@0 | 351 | bool LessThan(const nsSMILInstanceTime* aElem1, |
michael@0 | 352 | const nsSMILInstanceTime* aElem2) const; |
michael@0 | 353 | }; |
michael@0 | 354 | |
michael@0 | 355 | struct NotifyTimeDependentsParams { |
michael@0 | 356 | nsSMILTimedElement* mTimedElement; |
michael@0 | 357 | nsSMILTimeContainer* mTimeContainer; |
michael@0 | 358 | }; |
michael@0 | 359 | |
michael@0 | 360 | // Templated helper functions |
michael@0 | 361 | template <class TestFunctor> |
michael@0 | 362 | void RemoveInstanceTimes(InstanceTimeList& aArray, TestFunctor& aTest); |
michael@0 | 363 | |
michael@0 | 364 | // |
michael@0 | 365 | // Implementation helpers |
michael@0 | 366 | // |
michael@0 | 367 | |
michael@0 | 368 | nsresult SetBeginSpec(const nsAString& aBeginSpec, |
michael@0 | 369 | Element* aContextNode, |
michael@0 | 370 | RemovalTestFunction aRemove); |
michael@0 | 371 | nsresult SetEndSpec(const nsAString& aEndSpec, |
michael@0 | 372 | Element* aContextNode, |
michael@0 | 373 | RemovalTestFunction aRemove); |
michael@0 | 374 | nsresult SetSimpleDuration(const nsAString& aDurSpec); |
michael@0 | 375 | nsresult SetMin(const nsAString& aMinSpec); |
michael@0 | 376 | nsresult SetMax(const nsAString& aMaxSpec); |
michael@0 | 377 | nsresult SetRestart(const nsAString& aRestartSpec); |
michael@0 | 378 | nsresult SetRepeatCount(const nsAString& aRepeatCountSpec); |
michael@0 | 379 | nsresult SetRepeatDur(const nsAString& aRepeatDurSpec); |
michael@0 | 380 | nsresult SetFillMode(const nsAString& aFillModeSpec); |
michael@0 | 381 | |
michael@0 | 382 | void UnsetBeginSpec(RemovalTestFunction aRemove); |
michael@0 | 383 | void UnsetEndSpec(RemovalTestFunction aRemove); |
michael@0 | 384 | void UnsetSimpleDuration(); |
michael@0 | 385 | void UnsetMin(); |
michael@0 | 386 | void UnsetMax(); |
michael@0 | 387 | void UnsetRestart(); |
michael@0 | 388 | void UnsetRepeatCount(); |
michael@0 | 389 | void UnsetRepeatDur(); |
michael@0 | 390 | void UnsetFillMode(); |
michael@0 | 391 | |
michael@0 | 392 | nsresult SetBeginOrEndSpec(const nsAString& aSpec, |
michael@0 | 393 | Element* aContextNode, |
michael@0 | 394 | bool aIsBegin, |
michael@0 | 395 | RemovalTestFunction aRemove); |
michael@0 | 396 | void ClearSpecs(TimeValueSpecList& aSpecs, |
michael@0 | 397 | InstanceTimeList& aInstances, |
michael@0 | 398 | RemovalTestFunction aRemove); |
michael@0 | 399 | void ClearIntervals(); |
michael@0 | 400 | void DoSampleAt(nsSMILTime aContainerTime, bool aEndOnly); |
michael@0 | 401 | |
michael@0 | 402 | /** |
michael@0 | 403 | * Helper function to check for an early end and, if necessary, update the |
michael@0 | 404 | * current interval accordingly. |
michael@0 | 405 | * |
michael@0 | 406 | * See SMIL 3.0, section 5.4.5, Element life cycle, "Active Time - Playing an |
michael@0 | 407 | * interval" for a description of ending early. |
michael@0 | 408 | * |
michael@0 | 409 | * @param aSampleTime The current sample time. Early ends should only be |
michael@0 | 410 | * applied at the last possible moment (i.e. if they are at |
michael@0 | 411 | * or before the current sample time) and only if the |
michael@0 | 412 | * current interval is not already ending. |
michael@0 | 413 | * @return true if the end time of the current interval was updated, |
michael@0 | 414 | * false otherwise. |
michael@0 | 415 | */ |
michael@0 | 416 | bool ApplyEarlyEnd(const nsSMILTimeValue& aSampleTime); |
michael@0 | 417 | |
michael@0 | 418 | /** |
michael@0 | 419 | * Clears certain state in response to the element restarting. |
michael@0 | 420 | * |
michael@0 | 421 | * This state is described in SMIL 3.0, section 5.4.3, Resetting element state |
michael@0 | 422 | */ |
michael@0 | 423 | void Reset(); |
michael@0 | 424 | |
michael@0 | 425 | /** |
michael@0 | 426 | * Completes a seek operation by sending appropriate events and, in the case |
michael@0 | 427 | * of a backwards seek, updating the state of timing information that was |
michael@0 | 428 | * previously considered historical. |
michael@0 | 429 | */ |
michael@0 | 430 | void DoPostSeek(); |
michael@0 | 431 | |
michael@0 | 432 | /** |
michael@0 | 433 | * Unmarks instance times that were previously preserved because they were |
michael@0 | 434 | * considered important historical milestones but are no longer such because |
michael@0 | 435 | * a backwards seek has been performed. |
michael@0 | 436 | */ |
michael@0 | 437 | void UnpreserveInstanceTimes(InstanceTimeList& aList); |
michael@0 | 438 | |
michael@0 | 439 | /** |
michael@0 | 440 | * Helper function to iterate through this element's accumulated timing |
michael@0 | 441 | * information (specifically old nsSMILIntervals and nsSMILTimeInstanceTimes) |
michael@0 | 442 | * and discard items that are no longer needed or exceed some threshold of |
michael@0 | 443 | * accumulated state. |
michael@0 | 444 | */ |
michael@0 | 445 | void FilterHistory(); |
michael@0 | 446 | |
michael@0 | 447 | // Helper functions for FilterHistory to clear old nsSMILIntervals and |
michael@0 | 448 | // nsSMILInstanceTimes respectively. |
michael@0 | 449 | void FilterIntervals(); |
michael@0 | 450 | void FilterInstanceTimes(InstanceTimeList& aList); |
michael@0 | 451 | |
michael@0 | 452 | /** |
michael@0 | 453 | * Calculates the next acceptable interval for this element after the |
michael@0 | 454 | * specified interval, or, if no previous interval is specified, it will be |
michael@0 | 455 | * the first interval with an end time after t=0. |
michael@0 | 456 | * |
michael@0 | 457 | * @see SMILANIM 3.6.8 |
michael@0 | 458 | * |
michael@0 | 459 | * @param aPrevInterval The previous interval used. If supplied, the first |
michael@0 | 460 | * interval that begins after aPrevInterval will be |
michael@0 | 461 | * returned. May be nullptr. |
michael@0 | 462 | * @param aReplacedInterval The interval that is being updated (if any). This |
michael@0 | 463 | * used to ensure we don't return interval endpoints |
michael@0 | 464 | * that are dependent on themselves. May be nullptr. |
michael@0 | 465 | * @param aFixedBeginTime The time to use for the start of the interval. This |
michael@0 | 466 | * is used when only the endpoint of the interval |
michael@0 | 467 | * should be updated such as when the animation is in |
michael@0 | 468 | * the ACTIVE state. May be nullptr. |
michael@0 | 469 | * @param[out] aResult The next interval. Will be unchanged if no suitable |
michael@0 | 470 | * interval was found (in which case false will be |
michael@0 | 471 | * returned). |
michael@0 | 472 | * @return true if a suitable interval was found, false otherwise. |
michael@0 | 473 | */ |
michael@0 | 474 | bool GetNextInterval(const nsSMILInterval* aPrevInterval, |
michael@0 | 475 | const nsSMILInterval* aReplacedInterval, |
michael@0 | 476 | const nsSMILInstanceTime* aFixedBeginTime, |
michael@0 | 477 | nsSMILInterval& aResult) const; |
michael@0 | 478 | nsSMILInstanceTime* GetNextGreater(const InstanceTimeList& aList, |
michael@0 | 479 | const nsSMILTimeValue& aBase, |
michael@0 | 480 | int32_t& aPosition) const; |
michael@0 | 481 | nsSMILInstanceTime* GetNextGreaterOrEqual(const InstanceTimeList& aList, |
michael@0 | 482 | const nsSMILTimeValue& aBase, |
michael@0 | 483 | int32_t& aPosition) const; |
michael@0 | 484 | nsSMILTimeValue CalcActiveEnd(const nsSMILTimeValue& aBegin, |
michael@0 | 485 | const nsSMILTimeValue& aEnd) const; |
michael@0 | 486 | nsSMILTimeValue GetRepeatDuration() const; |
michael@0 | 487 | nsSMILTimeValue ApplyMinAndMax(const nsSMILTimeValue& aDuration) const; |
michael@0 | 488 | nsSMILTime ActiveTimeToSimpleTime(nsSMILTime aActiveTime, |
michael@0 | 489 | uint32_t& aRepeatIteration); |
michael@0 | 490 | nsSMILInstanceTime* CheckForEarlyEnd( |
michael@0 | 491 | const nsSMILTimeValue& aContainerTime) const; |
michael@0 | 492 | void UpdateCurrentInterval(bool aForceChangeNotice = false); |
michael@0 | 493 | void SampleSimpleTime(nsSMILTime aActiveTime); |
michael@0 | 494 | void SampleFillValue(); |
michael@0 | 495 | nsresult AddInstanceTimeFromCurrentTime(nsSMILTime aCurrentTime, |
michael@0 | 496 | double aOffsetSeconds, bool aIsBegin); |
michael@0 | 497 | void RegisterMilestone(); |
michael@0 | 498 | bool GetNextMilestone(nsSMILMilestone& aNextMilestone) const; |
michael@0 | 499 | |
michael@0 | 500 | // Notification methods. Note that these notifications can result in nested |
michael@0 | 501 | // calls to this same object. Therefore, |
michael@0 | 502 | // (i) we should not perform notification until this object is in |
michael@0 | 503 | // a consistent state to receive callbacks, and |
michael@0 | 504 | // (ii) after calling these methods we must assume that the state of the |
michael@0 | 505 | // element may have changed. |
michael@0 | 506 | void NotifyNewInterval(); |
michael@0 | 507 | void NotifyChangedInterval(nsSMILInterval* aInterval, |
michael@0 | 508 | bool aBeginObjectChanged, |
michael@0 | 509 | bool aEndObjectChanged); |
michael@0 | 510 | |
michael@0 | 511 | void FireTimeEventAsync(uint32_t aMsg, int32_t aDetail); |
michael@0 | 512 | const nsSMILInstanceTime* GetEffectiveBeginInstance() const; |
michael@0 | 513 | const nsSMILInterval* GetPreviousInterval() const; |
michael@0 | 514 | bool HasPlayed() const { return !mOldIntervals.IsEmpty(); } |
michael@0 | 515 | bool HasClientInFillRange() const; |
michael@0 | 516 | bool EndHasEventConditions() const; |
michael@0 | 517 | bool AreEndTimesDependentOn( |
michael@0 | 518 | const nsSMILInstanceTime* aBase) const; |
michael@0 | 519 | |
michael@0 | 520 | // Reset the current interval by first passing ownership to a temporary |
michael@0 | 521 | // variable so that if Unlink() results in us receiving a callback, |
michael@0 | 522 | // mCurrentInterval will be nullptr and we will be in a consistent state. |
michael@0 | 523 | void ResetCurrentInterval() |
michael@0 | 524 | { |
michael@0 | 525 | if (mCurrentInterval) { |
michael@0 | 526 | // Transfer ownership to temp var. (This sets mCurrentInterval to null.) |
michael@0 | 527 | nsAutoPtr<nsSMILInterval> interval(mCurrentInterval); |
michael@0 | 528 | interval->Unlink(); |
michael@0 | 529 | } |
michael@0 | 530 | } |
michael@0 | 531 | |
michael@0 | 532 | // Hashtable callback methods |
michael@0 | 533 | static PLDHashOperator NotifyNewIntervalCallback( |
michael@0 | 534 | TimeValueSpecPtrKey* aKey, void* aData); |
michael@0 | 535 | |
michael@0 | 536 | // |
michael@0 | 537 | // Members |
michael@0 | 538 | // |
michael@0 | 539 | mozilla::dom::SVGAnimationElement* mAnimationElement; // [weak] won't outlive |
michael@0 | 540 | // owner |
michael@0 | 541 | TimeValueSpecList mBeginSpecs; // [strong] |
michael@0 | 542 | TimeValueSpecList mEndSpecs; // [strong] |
michael@0 | 543 | |
michael@0 | 544 | nsSMILTimeValue mSimpleDur; |
michael@0 | 545 | |
michael@0 | 546 | nsSMILRepeatCount mRepeatCount; |
michael@0 | 547 | nsSMILTimeValue mRepeatDur; |
michael@0 | 548 | |
michael@0 | 549 | nsSMILTimeValue mMin; |
michael@0 | 550 | nsSMILTimeValue mMax; |
michael@0 | 551 | |
michael@0 | 552 | enum nsSMILFillMode |
michael@0 | 553 | { |
michael@0 | 554 | FILL_REMOVE, |
michael@0 | 555 | FILL_FREEZE |
michael@0 | 556 | }; |
michael@0 | 557 | nsSMILFillMode mFillMode; |
michael@0 | 558 | static nsAttrValue::EnumTable sFillModeTable[]; |
michael@0 | 559 | |
michael@0 | 560 | enum nsSMILRestartMode |
michael@0 | 561 | { |
michael@0 | 562 | RESTART_ALWAYS, |
michael@0 | 563 | RESTART_WHENNOTACTIVE, |
michael@0 | 564 | RESTART_NEVER |
michael@0 | 565 | }; |
michael@0 | 566 | nsSMILRestartMode mRestartMode; |
michael@0 | 567 | static nsAttrValue::EnumTable sRestartModeTable[]; |
michael@0 | 568 | |
michael@0 | 569 | InstanceTimeList mBeginInstances; |
michael@0 | 570 | InstanceTimeList mEndInstances; |
michael@0 | 571 | uint32_t mInstanceSerialIndex; |
michael@0 | 572 | |
michael@0 | 573 | nsSMILAnimationFunction* mClient; |
michael@0 | 574 | nsAutoPtr<nsSMILInterval> mCurrentInterval; |
michael@0 | 575 | IntervalList mOldIntervals; |
michael@0 | 576 | uint32_t mCurrentRepeatIteration; |
michael@0 | 577 | nsSMILMilestone mPrevRegisteredMilestone; |
michael@0 | 578 | static const nsSMILMilestone sMaxMilestone; |
michael@0 | 579 | static const uint8_t sMaxNumIntervals; |
michael@0 | 580 | static const uint8_t sMaxNumInstanceTimes; |
michael@0 | 581 | |
michael@0 | 582 | // Set of dependent time value specs to be notified when establishing a new |
michael@0 | 583 | // current interval. Change notifications and delete notifications are handled |
michael@0 | 584 | // by the interval. |
michael@0 | 585 | // |
michael@0 | 586 | // [weak] The nsSMILTimeValueSpec objects register themselves and unregister |
michael@0 | 587 | // on destruction. Likewise, we notify them when we are destroyed. |
michael@0 | 588 | TimeValueSpecHashSet mTimeDependents; |
michael@0 | 589 | |
michael@0 | 590 | /** |
michael@0 | 591 | * The state of the element in its life-cycle. These states are based on the |
michael@0 | 592 | * element life-cycle described in SMILANIM 3.6.8 |
michael@0 | 593 | */ |
michael@0 | 594 | enum nsSMILElementState |
michael@0 | 595 | { |
michael@0 | 596 | STATE_STARTUP, |
michael@0 | 597 | STATE_WAITING, |
michael@0 | 598 | STATE_ACTIVE, |
michael@0 | 599 | STATE_POSTACTIVE |
michael@0 | 600 | }; |
michael@0 | 601 | nsSMILElementState mElementState; |
michael@0 | 602 | |
michael@0 | 603 | enum nsSMILSeekState |
michael@0 | 604 | { |
michael@0 | 605 | SEEK_NOT_SEEKING, |
michael@0 | 606 | SEEK_FORWARD_FROM_ACTIVE, |
michael@0 | 607 | SEEK_FORWARD_FROM_INACTIVE, |
michael@0 | 608 | SEEK_BACKWARD_FROM_ACTIVE, |
michael@0 | 609 | SEEK_BACKWARD_FROM_INACTIVE |
michael@0 | 610 | }; |
michael@0 | 611 | nsSMILSeekState mSeekState; |
michael@0 | 612 | |
michael@0 | 613 | // Used to batch updates to the timing model |
michael@0 | 614 | class AutoIntervalUpdateBatcher; |
michael@0 | 615 | bool mDeferIntervalUpdates; |
michael@0 | 616 | bool mDoDeferredUpdate; // Set if an update to the current interval was |
michael@0 | 617 | // requested while mDeferIntervalUpdates was set |
michael@0 | 618 | |
michael@0 | 619 | // Stack-based helper class to call UpdateCurrentInterval when it is destroyed |
michael@0 | 620 | class AutoIntervalUpdater; |
michael@0 | 621 | |
michael@0 | 622 | // Recursion depth checking |
michael@0 | 623 | uint8_t mDeleteCount; |
michael@0 | 624 | uint8_t mUpdateIntervalRecursionDepth; |
michael@0 | 625 | static const uint8_t sMaxUpdateIntervalRecursionDepth; |
michael@0 | 626 | }; |
michael@0 | 627 | |
michael@0 | 628 | #endif // NS_SMILTIMEDELEMENT_H_ |