Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/svg/nsSVGEnum.cpp
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
#include "nsError.h"
8
#include "nsSVGAttrTearoffTable.h"
9
#include "nsSVGEnum.h"
10
#include "nsAtom.h"
11
#include "nsSVGElement.h"
12
#include "nsSMILValue.h"
13
#include "SMILEnumType.h"
14
15
using namespace mozilla;
16
using namespace mozilla::dom;
17
18
static nsSVGAttrTearoffTable<nsSVGEnum, nsSVGEnum::DOMAnimatedEnum>
19
  sSVGAnimatedEnumTearoffTable;
20
21
nsSVGEnumMapping *
22
nsSVGEnum::GetMapping(nsSVGElement *aSVGElement)
23
0
{
24
0
  nsSVGElement::EnumAttributesInfo info = aSVGElement->GetEnumInfo();
25
0
26
0
  NS_ASSERTION(info.mEnumCount > 0 && mAttrEnum < info.mEnumCount,
27
0
               "mapping request for a non-attrib enum");
28
0
29
0
  return info.mEnumInfo[mAttrEnum].mMapping;
30
0
}
31
32
nsresult
33
nsSVGEnum::SetBaseValueAtom(const nsAtom* aValue, nsSVGElement *aSVGElement)
34
0
{
35
0
  nsSVGEnumMapping *mapping = GetMapping(aSVGElement);
36
0
37
0
  while (mapping && mapping->mKey) {
38
0
    if (aValue == *(mapping->mKey)) {
39
0
      mIsBaseSet = true;
40
0
      if (mBaseVal != mapping->mVal) {
41
0
        mBaseVal = mapping->mVal;
42
0
        if (!mIsAnimated) {
43
0
          mAnimVal = mBaseVal;
44
0
        }
45
0
        else {
46
0
          aSVGElement->AnimationNeedsResample();
47
0
        }
48
0
        // We don't need to call DidChange* here - we're only called by
49
0
        // nsSVGElement::ParseAttribute under Element::SetAttr,
50
0
        // which takes care of notifying.
51
0
      }
52
0
      return NS_OK;
53
0
    }
54
0
    mapping++;
55
0
  }
56
0
57
0
  return NS_ERROR_DOM_TYPE_ERR;
58
0
}
59
60
nsAtom*
61
nsSVGEnum::GetBaseValueAtom(nsSVGElement *aSVGElement)
62
0
{
63
0
  nsSVGEnumMapping *mapping = GetMapping(aSVGElement);
64
0
65
0
  while (mapping && mapping->mKey) {
66
0
    if (mBaseVal == mapping->mVal) {
67
0
      return *mapping->mKey;
68
0
    }
69
0
    mapping++;
70
0
  }
71
0
  NS_ERROR("unknown enumeration value");
72
0
  return nsGkAtoms::_empty;
73
0
}
74
75
nsresult
76
nsSVGEnum::SetBaseValue(uint16_t aValue,
77
                        nsSVGElement *aSVGElement)
78
0
{
79
0
  nsSVGEnumMapping *mapping = GetMapping(aSVGElement);
80
0
81
0
  while (mapping && mapping->mKey) {
82
0
    if (mapping->mVal == aValue) {
83
0
      mIsBaseSet = true;
84
0
      if (mBaseVal != uint8_t(aValue)) {
85
0
        mBaseVal = uint8_t(aValue);
86
0
        if (!mIsAnimated) {
87
0
          mAnimVal = mBaseVal;
88
0
        }
89
0
        else {
90
0
          aSVGElement->AnimationNeedsResample();
91
0
        }
92
0
        aSVGElement->DidChangeEnum(mAttrEnum);
93
0
      }
94
0
      return NS_OK;
95
0
    }
96
0
    mapping++;
97
0
  }
98
0
  return NS_ERROR_DOM_TYPE_ERR;
99
0
}
100
101
void
102
nsSVGEnum::SetAnimValue(uint16_t aValue, nsSVGElement *aSVGElement)
103
0
{
104
0
  if (mIsAnimated && aValue == mAnimVal) {
105
0
    return;
106
0
  }
107
0
  mAnimVal = aValue;
108
0
  mIsAnimated = true;
109
0
  aSVGElement->DidAnimateEnum(mAttrEnum);
110
0
}
111
112
already_AddRefed<SVGAnimatedEnumeration>
113
nsSVGEnum::ToDOMAnimatedEnum(nsSVGElement* aSVGElement)
114
0
{
115
0
  RefPtr<DOMAnimatedEnum> domAnimatedEnum =
116
0
    sSVGAnimatedEnumTearoffTable.GetTearoff(this);
117
0
  if (!domAnimatedEnum) {
118
0
    domAnimatedEnum = new DOMAnimatedEnum(this, aSVGElement);
119
0
    sSVGAnimatedEnumTearoffTable.AddTearoff(this, domAnimatedEnum);
120
0
  }
121
0
122
0
  return domAnimatedEnum.forget();
123
0
}
124
125
nsSVGEnum::DOMAnimatedEnum::~DOMAnimatedEnum()
126
0
{
127
0
  sSVGAnimatedEnumTearoffTable.RemoveTearoff(mVal);
128
0
}
129
130
UniquePtr<nsISMILAttr>
131
nsSVGEnum::ToSMILAttr(nsSVGElement *aSVGElement)
132
0
{
133
0
  return MakeUnique<SMILEnum>(this, aSVGElement);
134
0
}
135
136
nsresult
137
nsSVGEnum::SMILEnum::ValueFromString(const nsAString& aStr,
138
                                     const dom::SVGAnimationElement* /*aSrcElement*/,
139
                                     nsSMILValue& aValue,
140
                                     bool& aPreventCachingOfSandwich) const
141
0
{
142
0
  nsAtom *valAtom = NS_GetStaticAtom(aStr);
143
0
  if (valAtom) {
144
0
    nsSVGEnumMapping *mapping = mVal->GetMapping(mSVGElement);
145
0
146
0
    while (mapping && mapping->mKey) {
147
0
      if (valAtom == *(mapping->mKey)) {
148
0
        nsSMILValue val(SMILEnumType::Singleton());
149
0
        val.mU.mUint = mapping->mVal;
150
0
        aValue = val;
151
0
        aPreventCachingOfSandwich = false;
152
0
        return NS_OK;
153
0
      }
154
0
      mapping++;
155
0
    }
156
0
  }
157
0
158
0
  // only a warning since authors may mistype attribute values
159
0
  NS_WARNING("unknown enumeration key");
160
0
  return NS_ERROR_FAILURE;
161
0
}
162
163
nsSMILValue
164
nsSVGEnum::SMILEnum::GetBaseValue() const
165
0
{
166
0
  nsSMILValue val(SMILEnumType::Singleton());
167
0
  val.mU.mUint = mVal->mBaseVal;
168
0
  return val;
169
0
}
170
171
void
172
nsSVGEnum::SMILEnum::ClearAnimValue()
173
0
{
174
0
  if (mVal->mIsAnimated) {
175
0
    mVal->mIsAnimated = false;
176
0
    mVal->mAnimVal = mVal->mBaseVal;
177
0
    mSVGElement->DidAnimateEnum(mVal->mAttrEnum);
178
0
  }
179
0
}
180
181
nsresult
182
nsSVGEnum::SMILEnum::SetAnimValue(const nsSMILValue& aValue)
183
0
{
184
0
  NS_ASSERTION(aValue.mType == SMILEnumType::Singleton(),
185
0
               "Unexpected type to assign animated value");
186
0
  if (aValue.mType == SMILEnumType::Singleton()) {
187
0
    MOZ_ASSERT(aValue.mU.mUint <= USHRT_MAX,
188
0
               "Very large enumerated value - too big for uint16_t");
189
0
    mVal->SetAnimValue(uint16_t(aValue.mU.mUint), mSVGElement);
190
0
  }
191
0
  return NS_OK;
192
0
}