Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/html/HTMLMeterElement.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 "HTMLMeterElement.h"
8
#include "mozilla/EventStates.h"
9
#include "mozilla/dom/HTMLMeterElementBinding.h"
10
11
NS_IMPL_NS_NEW_HTML_ELEMENT(Meter)
12
13
namespace mozilla {
14
namespace dom {
15
16
const double HTMLMeterElement::kDefaultValue =  0.0;
17
const double HTMLMeterElement::kDefaultMin   =  0.0;
18
const double HTMLMeterElement::kDefaultMax   =  1.0;
19
20
21
HTMLMeterElement::HTMLMeterElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
22
  : nsGenericHTMLElement(std::move(aNodeInfo))
23
0
{
24
0
}
25
26
HTMLMeterElement::~HTMLMeterElement()
27
0
{
28
0
}
29
30
NS_IMPL_ELEMENT_CLONE(HTMLMeterElement)
31
32
EventStates
33
HTMLMeterElement::IntrinsicState() const
34
0
{
35
0
  EventStates state = nsGenericHTMLElement::IntrinsicState();
36
0
37
0
  state |= GetOptimumState();
38
0
39
0
  return state;
40
0
}
41
42
bool
43
HTMLMeterElement::ParseAttribute(int32_t aNamespaceID,
44
                                 nsAtom* aAttribute,
45
                                 const nsAString& aValue,
46
                                 nsIPrincipal* aMaybeScriptedPrincipal,
47
                                 nsAttrValue& aResult)
48
0
{
49
0
  if (aNamespaceID == kNameSpaceID_None) {
50
0
    if (aAttribute == nsGkAtoms::value || aAttribute == nsGkAtoms::max ||
51
0
        aAttribute == nsGkAtoms::min   || aAttribute == nsGkAtoms::low ||
52
0
        aAttribute == nsGkAtoms::high  || aAttribute == nsGkAtoms::optimum) {
53
0
      return aResult.ParseDoubleValue(aValue);
54
0
    }
55
0
  }
56
0
57
0
  return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute,
58
0
                                              aValue,
59
0
                                              aMaybeScriptedPrincipal,
60
0
                                              aResult);
61
0
}
62
63
/*
64
 * Value getters :
65
 * const getters used by XPCOM methods and by IntrinsicState
66
 */
67
68
double
69
HTMLMeterElement::Min() const
70
0
{
71
0
  /**
72
0
   * If the attribute min is defined, the minimum is this value.
73
0
   * Otherwise, the minimum is the default value.
74
0
   */
75
0
  const nsAttrValue* attrMin = mAttrs.GetAttr(nsGkAtoms::min);
76
0
  if (attrMin && attrMin->Type() == nsAttrValue::eDoubleValue) {
77
0
    return attrMin->GetDoubleValue();
78
0
  }
79
0
  return kDefaultMin;
80
0
}
81
82
double
83
HTMLMeterElement::Max() const
84
0
{
85
0
  /**
86
0
   * If the attribute max is defined, the maximum is this value.
87
0
   * Otherwise, the maximum is the default value.
88
0
   * If the maximum value is less than the minimum value,
89
0
   * the maximum value is the same as the minimum value.
90
0
   */
91
0
  double max;
92
0
93
0
  const nsAttrValue* attrMax = mAttrs.GetAttr(nsGkAtoms::max);
94
0
  if (attrMax && attrMax->Type() == nsAttrValue::eDoubleValue) {
95
0
    max = attrMax->GetDoubleValue();
96
0
  } else {
97
0
    max = kDefaultMax;
98
0
  }
99
0
100
0
  return std::max(max, Min());
101
0
}
102
103
double
104
HTMLMeterElement::Value() const
105
0
{
106
0
  /**
107
0
   * If the attribute value is defined, the actual value is this value.
108
0
   * Otherwise, the actual value is the default value.
109
0
   * If the actual value is less than the minimum value,
110
0
   * the actual value is the same as the minimum value.
111
0
   * If the actual value is greater than the maximum value,
112
0
   * the actual value is the same as the maximum value.
113
0
   */
114
0
  double value;
115
0
116
0
  const nsAttrValue* attrValue = mAttrs.GetAttr(nsGkAtoms::value);
117
0
  if (attrValue && attrValue->Type() == nsAttrValue::eDoubleValue) {
118
0
    value = attrValue->GetDoubleValue();
119
0
  } else {
120
0
    value = kDefaultValue;
121
0
  }
122
0
123
0
  double min = Min();
124
0
125
0
  if (value <= min) {
126
0
    return min;
127
0
  }
128
0
129
0
  return std::min(value, Max());
130
0
}
131
132
double
133
HTMLMeterElement::Low() const
134
0
{
135
0
  /**
136
0
   * If the low value is defined, the low value is this value.
137
0
   * Otherwise, the low value is the minimum value.
138
0
   * If the low value is less than the minimum value,
139
0
   * the low value is the same as the minimum value.
140
0
   * If the low value is greater than the maximum value,
141
0
   * the low value is the same as the maximum value.
142
0
   */
143
0
144
0
  double min = Min();
145
0
146
0
  const nsAttrValue* attrLow = mAttrs.GetAttr(nsGkAtoms::low);
147
0
  if (!attrLow || attrLow->Type() != nsAttrValue::eDoubleValue) {
148
0
    return min;
149
0
  }
150
0
151
0
  double low = attrLow->GetDoubleValue();
152
0
153
0
  if (low <= min) {
154
0
    return min;
155
0
  }
156
0
157
0
  return std::min(low, Max());
158
0
}
159
160
double
161
HTMLMeterElement::High() const
162
0
{
163
0
  /**
164
0
   * If the high value is defined, the high value is this value.
165
0
   * Otherwise, the high value is the maximum value.
166
0
   * If the high value is less than the low value,
167
0
   * the high value is the same as the low value.
168
0
   * If the high value is greater than the maximum value,
169
0
   * the high value is the same as the maximum value.
170
0
   */
171
0
172
0
  double max = Max();
173
0
174
0
  const nsAttrValue* attrHigh = mAttrs.GetAttr(nsGkAtoms::high);
175
0
  if (!attrHigh || attrHigh->Type() != nsAttrValue::eDoubleValue) {
176
0
    return max;
177
0
  }
178
0
179
0
  double high = attrHigh->GetDoubleValue();
180
0
181
0
  if (high >= max) {
182
0
    return max;
183
0
  }
184
0
185
0
  return std::max(high, Low());
186
0
}
187
188
double
189
HTMLMeterElement::Optimum() const
190
0
{
191
0
  /**
192
0
   * If the optimum value is defined, the optimum value is this value.
193
0
   * Otherwise, the optimum value is the midpoint between
194
0
   * the minimum value and the maximum value :
195
0
   * min + (max - min)/2 = (min + max)/2
196
0
   * If the optimum value is less than the minimum value,
197
0
   * the optimum value is the same as the minimum value.
198
0
   * If the optimum value is greater than the maximum value,
199
0
   * the optimum value is the same as the maximum value.
200
0
   */
201
0
202
0
  double max = Max();
203
0
204
0
  double min = Min();
205
0
206
0
  const nsAttrValue* attrOptimum =
207
0
              mAttrs.GetAttr(nsGkAtoms::optimum);
208
0
  if (!attrOptimum || attrOptimum->Type() != nsAttrValue::eDoubleValue) {
209
0
    return (min + max) / 2.0;
210
0
  }
211
0
212
0
  double optimum = attrOptimum->GetDoubleValue();
213
0
214
0
  if (optimum <= min) {
215
0
    return min;
216
0
  }
217
0
218
0
  return std::min(optimum, max);
219
0
}
220
221
EventStates
222
HTMLMeterElement::GetOptimumState() const
223
0
{
224
0
  /*
225
0
   * If the optimum value is in [minimum, low[,
226
0
   *     return if the value is in optimal, suboptimal or sub-suboptimal region
227
0
   *
228
0
   * If the optimum value is in [low, high],
229
0
   *     return if the value is in optimal or suboptimal region
230
0
   *
231
0
   * If the optimum value is in ]high, maximum],
232
0
   *     return if the value is in optimal, suboptimal or sub-suboptimal region
233
0
   */
234
0
  double value = Value();
235
0
  double low = Low();
236
0
  double high = High();
237
0
  double optimum = Optimum();
238
0
239
0
  if (optimum < low) {
240
0
    if (value < low) {
241
0
      return NS_EVENT_STATE_OPTIMUM;
242
0
    }
243
0
    if (value <= high) {
244
0
      return NS_EVENT_STATE_SUB_OPTIMUM;
245
0
    }
246
0
    return NS_EVENT_STATE_SUB_SUB_OPTIMUM;
247
0
  }
248
0
  if (optimum > high) {
249
0
    if (value > high) {
250
0
      return NS_EVENT_STATE_OPTIMUM;
251
0
    }
252
0
    if (value >= low) {
253
0
      return NS_EVENT_STATE_SUB_OPTIMUM;
254
0
    }
255
0
    return NS_EVENT_STATE_SUB_SUB_OPTIMUM;
256
0
  }
257
0
  // optimum in [low, high]
258
0
  if (value >= low && value <= high) {
259
0
    return NS_EVENT_STATE_OPTIMUM;
260
0
  }
261
0
  return NS_EVENT_STATE_SUB_OPTIMUM;
262
0
}
263
264
JSObject*
265
HTMLMeterElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
266
0
{
267
0
  return HTMLMeterElement_Binding::Wrap(aCx, this, aGivenProto);
268
0
}
269
270
} // namespace dom
271
} // namespace mozilla