HTMLMeterElement.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "HTMLMeterElement.h"
  6. #include "mozilla/EventStates.h"
  7. #include "mozilla/dom/HTMLMeterElementBinding.h"
  8. NS_IMPL_NS_NEW_HTML_ELEMENT(Meter)
  9. namespace mozilla {
  10. namespace dom {
  11. const double HTMLMeterElement::kDefaultValue = 0.0;
  12. const double HTMLMeterElement::kDefaultMin = 0.0;
  13. const double HTMLMeterElement::kDefaultMax = 1.0;
  14. HTMLMeterElement::HTMLMeterElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
  15. : nsGenericHTMLElement(aNodeInfo)
  16. {
  17. }
  18. HTMLMeterElement::~HTMLMeterElement()
  19. {
  20. }
  21. NS_IMPL_ELEMENT_CLONE(HTMLMeterElement)
  22. EventStates
  23. HTMLMeterElement::IntrinsicState() const
  24. {
  25. EventStates state = nsGenericHTMLElement::IntrinsicState();
  26. state |= GetOptimumState();
  27. return state;
  28. }
  29. bool
  30. HTMLMeterElement::ParseAttribute(int32_t aNamespaceID, nsIAtom* aAttribute,
  31. const nsAString& aValue, nsAttrValue& aResult)
  32. {
  33. if (aNamespaceID == kNameSpaceID_None) {
  34. if (aAttribute == nsGkAtoms::value || aAttribute == nsGkAtoms::max ||
  35. aAttribute == nsGkAtoms::min || aAttribute == nsGkAtoms::low ||
  36. aAttribute == nsGkAtoms::high || aAttribute == nsGkAtoms::optimum) {
  37. return aResult.ParseDoubleValue(aValue);
  38. }
  39. }
  40. return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute,
  41. aValue, aResult);
  42. }
  43. /*
  44. * Value getters :
  45. * const getters used by XPCOM methods and by IntrinsicState
  46. */
  47. double
  48. HTMLMeterElement::Min() const
  49. {
  50. /**
  51. * If the attribute min is defined, the minimum is this value.
  52. * Otherwise, the minimum is the default value.
  53. */
  54. const nsAttrValue* attrMin = mAttrsAndChildren.GetAttr(nsGkAtoms::min);
  55. if (attrMin && attrMin->Type() == nsAttrValue::eDoubleValue) {
  56. return attrMin->GetDoubleValue();
  57. }
  58. return kDefaultMin;
  59. }
  60. double
  61. HTMLMeterElement::Max() const
  62. {
  63. /**
  64. * If the attribute max is defined, the maximum is this value.
  65. * Otherwise, the maximum is the default value.
  66. * If the maximum value is less than the minimum value,
  67. * the maximum value is the same as the minimum value.
  68. */
  69. double max;
  70. const nsAttrValue* attrMax = mAttrsAndChildren.GetAttr(nsGkAtoms::max);
  71. if (attrMax && attrMax->Type() == nsAttrValue::eDoubleValue) {
  72. max = attrMax->GetDoubleValue();
  73. } else {
  74. max = kDefaultMax;
  75. }
  76. return std::max(max, Min());
  77. }
  78. double
  79. HTMLMeterElement::Value() const
  80. {
  81. /**
  82. * If the attribute value is defined, the actual value is this value.
  83. * Otherwise, the actual value is the default value.
  84. * If the actual value is less than the minimum value,
  85. * the actual value is the same as the minimum value.
  86. * If the actual value is greater than the maximum value,
  87. * the actual value is the same as the maximum value.
  88. */
  89. double value;
  90. const nsAttrValue* attrValue = mAttrsAndChildren.GetAttr(nsGkAtoms::value);
  91. if (attrValue && attrValue->Type() == nsAttrValue::eDoubleValue) {
  92. value = attrValue->GetDoubleValue();
  93. } else {
  94. value = kDefaultValue;
  95. }
  96. double min = Min();
  97. if (value <= min) {
  98. return min;
  99. }
  100. return std::min(value, Max());
  101. }
  102. double
  103. HTMLMeterElement::Low() const
  104. {
  105. /**
  106. * If the low value is defined, the low value is this value.
  107. * Otherwise, the low value is the minimum value.
  108. * If the low value is less than the minimum value,
  109. * the low value is the same as the minimum value.
  110. * If the low value is greater than the maximum value,
  111. * the low value is the same as the maximum value.
  112. */
  113. double min = Min();
  114. const nsAttrValue* attrLow = mAttrsAndChildren.GetAttr(nsGkAtoms::low);
  115. if (!attrLow || attrLow->Type() != nsAttrValue::eDoubleValue) {
  116. return min;
  117. }
  118. double low = attrLow->GetDoubleValue();
  119. if (low <= min) {
  120. return min;
  121. }
  122. return std::min(low, Max());
  123. }
  124. double
  125. HTMLMeterElement::High() const
  126. {
  127. /**
  128. * If the high value is defined, the high value is this value.
  129. * Otherwise, the high value is the maximum value.
  130. * If the high value is less than the low value,
  131. * the high value is the same as the low value.
  132. * If the high value is greater than the maximum value,
  133. * the high value is the same as the maximum value.
  134. */
  135. double max = Max();
  136. const nsAttrValue* attrHigh = mAttrsAndChildren.GetAttr(nsGkAtoms::high);
  137. if (!attrHigh || attrHigh->Type() != nsAttrValue::eDoubleValue) {
  138. return max;
  139. }
  140. double high = attrHigh->GetDoubleValue();
  141. if (high >= max) {
  142. return max;
  143. }
  144. return std::max(high, Low());
  145. }
  146. double
  147. HTMLMeterElement::Optimum() const
  148. {
  149. /**
  150. * If the optimum value is defined, the optimum value is this value.
  151. * Otherwise, the optimum value is the midpoint between
  152. * the minimum value and the maximum value :
  153. * min + (max - min)/2 = (min + max)/2
  154. * If the optimum value is less than the minimum value,
  155. * the optimum value is the same as the minimum value.
  156. * If the optimum value is greater than the maximum value,
  157. * the optimum value is the same as the maximum value.
  158. */
  159. double max = Max();
  160. double min = Min();
  161. const nsAttrValue* attrOptimum =
  162. mAttrsAndChildren.GetAttr(nsGkAtoms::optimum);
  163. if (!attrOptimum || attrOptimum->Type() != nsAttrValue::eDoubleValue) {
  164. return (min + max) / 2.0;
  165. }
  166. double optimum = attrOptimum->GetDoubleValue();
  167. if (optimum <= min) {
  168. return min;
  169. }
  170. return std::min(optimum, max);
  171. }
  172. EventStates
  173. HTMLMeterElement::GetOptimumState() const
  174. {
  175. /*
  176. * If the optimum value is in [minimum, low[,
  177. * return if the value is in optimal, suboptimal or sub-suboptimal region
  178. *
  179. * If the optimum value is in [low, high],
  180. * return if the value is in optimal or suboptimal region
  181. *
  182. * If the optimum value is in ]high, maximum],
  183. * return if the value is in optimal, suboptimal or sub-suboptimal region
  184. */
  185. double value = Value();
  186. double low = Low();
  187. double high = High();
  188. double optimum = Optimum();
  189. if (optimum < low) {
  190. if (value < low) {
  191. return NS_EVENT_STATE_OPTIMUM;
  192. }
  193. if (value <= high) {
  194. return NS_EVENT_STATE_SUB_OPTIMUM;
  195. }
  196. return NS_EVENT_STATE_SUB_SUB_OPTIMUM;
  197. }
  198. if (optimum > high) {
  199. if (value > high) {
  200. return NS_EVENT_STATE_OPTIMUM;
  201. }
  202. if (value >= low) {
  203. return NS_EVENT_STATE_SUB_OPTIMUM;
  204. }
  205. return NS_EVENT_STATE_SUB_SUB_OPTIMUM;
  206. }
  207. // optimum in [low, high]
  208. if (value >= low && value <= high) {
  209. return NS_EVENT_STATE_OPTIMUM;
  210. }
  211. return NS_EVENT_STATE_SUB_OPTIMUM;
  212. }
  213. JSObject*
  214. HTMLMeterElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
  215. {
  216. return HTMLMeterElementBinding::Wrap(aCx, this, aGivenProto);
  217. }
  218. } // namespace dom
  219. } // namespace mozilla