Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/smil/nsSMILTimeValueSpec.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef NS_SMILTIMEVALUESPEC_H_
8
#define NS_SMILTIMEVALUESPEC_H_
9
10
#include "mozilla/Attributes.h"
11
#include "mozilla/dom/IDTracker.h"
12
#include "nsSMILTimeValueSpecParams.h"
13
#include "nsStringFwd.h"
14
#include "nsIDOMEventListener.h"
15
16
class nsSMILTimeValue;
17
class nsSMILTimedElement;
18
class nsSMILTimeContainer;
19
class nsSMILInstanceTime;
20
class nsSMILInterval;
21
22
namespace mozilla {
23
namespace dom {
24
class Event;
25
} // namespace dom
26
27
class EventListenerManager;
28
} // namespace mozilla
29
30
//----------------------------------------------------------------------
31
// nsSMILTimeValueSpec class
32
//
33
// An individual element of a 'begin' or 'end' attribute, e.g. '5s', 'a.end'.
34
// This class handles the parsing of such specifications and performs the
35
// necessary event handling (for event and repeat specifications)
36
// and synchronisation (for syncbase specifications).
37
//
38
// For an overview of how this class is related to other SMIL time classes see
39
// the documentation in nsSMILTimeValue.h
40
41
class nsSMILTimeValueSpec
42
{
43
public:
44
  typedef mozilla::dom::Element Element;
45
  typedef mozilla::dom::Event Event;
46
  typedef mozilla::dom::IDTracker IDTracker;
47
48
  nsSMILTimeValueSpec(nsSMILTimedElement& aOwner, bool aIsBegin);
49
  ~nsSMILTimeValueSpec();
50
51
  nsresult SetSpec(const nsAString& aStringSpec, Element& aContextElement);
52
  void ResolveReferences(Element& aContextElement);
53
  bool IsEventBased() const;
54
55
  void     HandleNewInterval(nsSMILInterval& aInterval,
56
                             const nsSMILTimeContainer* aSrcContainer);
57
  void     HandleTargetElementChange(Element* aNewTarget);
58
59
  // For created nsSMILInstanceTime objects
60
  bool     DependsOnBegin() const;
61
  void     HandleChangedInstanceTime(const nsSMILInstanceTime& aBaseTime,
62
                                     const nsSMILTimeContainer* aSrcContainer,
63
                                     nsSMILInstanceTime& aInstanceTimeToUpdate,
64
                                     bool aObjectChanged);
65
  void     HandleDeletedInstanceTime(nsSMILInstanceTime& aInstanceTime);
66
67
  // Cycle-collection support
68
  void Traverse(nsCycleCollectionTraversalCallback* aCallback);
69
  void Unlink();
70
71
protected:
72
  void UpdateReferencedElement(Element* aFrom, Element* aTo);
73
  void UnregisterFromReferencedElement(Element* aElement);
74
  nsSMILTimedElement* GetTimedElement(Element* aElement);
75
  bool IsWhitelistedEvent();
76
  void RegisterEventListener(Element* aElement);
77
  void UnregisterEventListener(Element* aElement);
78
  void HandleEvent(Event* aEvent);
79
  bool CheckRepeatEventDetail(Event* aEvent);
80
  nsSMILTimeValue ConvertBetweenTimeContainers(const nsSMILTimeValue& aSrcTime,
81
                                      const nsSMILTimeContainer* aSrcContainer);
82
  bool ApplyOffset(nsSMILTimeValue& aTime) const;
83
84
  nsSMILTimedElement*           mOwner;
85
  bool                          mIsBegin; // Indicates if *we* are a begin spec,
86
                                          // not to be confused with
87
                                          // mParams.mSyncBegin which indicates
88
                                          // if we're synced with the begin of
89
                                          // the target.
90
  nsSMILTimeValueSpecParams     mParams;
91
92
  /**
93
   * If our nsSMILTimeValueSpec exists for a 'begin' or 'end' attribute with a
94
   * value that specifies a time that is relative to the animation of some
95
   * other element, it will create an instance of this class to reference and
96
   * track that other element.  For example, if the nsSMILTimeValueSpec is for
97
   * end='a.end+2s', an instance of this class will be created to track the
98
   * element associated with the element ID "a".  This class will notify the
99
   * nsSMILTimeValueSpec if the element that that ID identifies changes to a
100
   * different element (or none).
101
   */
102
  class TimeReferenceTracker final : public IDTracker
103
  {
104
  public:
105
    explicit TimeReferenceTracker(nsSMILTimeValueSpec* aOwner)
106
      : mSpec(aOwner)
107
0
    {}
108
0
    void ResetWithElement(Element* aTo) {
109
0
      RefPtr<Element> from = get();
110
0
      Unlink();
111
0
      ElementChanged(from, aTo);
112
0
    }
113
114
  protected:
115
    virtual void ElementChanged(Element* aFrom, Element* aTo) override
116
0
    {
117
0
      IDTracker::ElementChanged(aFrom, aTo);
118
0
      mSpec->UpdateReferencedElement(aFrom, aTo);
119
0
    }
120
0
    virtual bool IsPersistent() override { return true; }
121
  private:
122
    nsSMILTimeValueSpec* mSpec;
123
  };
124
125
  TimeReferenceTracker mReferencedElement;
126
127
  class EventListener final : public nsIDOMEventListener
128
  {
129
0
    ~EventListener() {}
130
  public:
131
0
    explicit EventListener(nsSMILTimeValueSpec* aOwner) : mSpec(aOwner) { }
132
    void Disconnect()
133
0
    {
134
0
      mSpec = nullptr;
135
0
    }
136
137
    NS_DECL_ISUPPORTS
138
    NS_DECL_NSIDOMEVENTLISTENER
139
140
  private:
141
    nsSMILTimeValueSpec* mSpec;
142
  };
143
  RefPtr<EventListener> mEventListener;
144
};
145
146
#endif // NS_SMILTIMEVALUESPEC_H_