PageRenderTime 39ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/third_party/WebKit/Source/core/svg/SVGLengthTearOff.cpp

https://gitlab.com/0072016/Facebook-SDK-
C++ | 239 lines | 174 code | 35 blank | 30 comment | 46 complexity | c53552a0fdf77b946dfa2de69c40cad2 MD5 | raw file
  1. /*
  2. * Copyright (C) 2014 Google Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are
  6. * met:
  7. *
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above
  11. * copyright notice, this list of conditions and the following disclaimer
  12. * in the documentation and/or other materials provided with the
  13. * distribution.
  14. * * Neither the name of Google Inc. nor the names of its
  15. * contributors may be used to endorse or promote products derived from
  16. * this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #include "core/svg/SVGLengthTearOff.h"
  31. #include "bindings/core/v8/ExceptionState.h"
  32. #include "core/dom/ExceptionCode.h"
  33. #include "core/svg/SVGElement.h"
  34. namespace blink {
  35. namespace {
  36. inline bool isValidLengthUnit(CSSPrimitiveValue::UnitType unit)
  37. {
  38. return unit == CSSPrimitiveValue::UnitType::Number
  39. || unit == CSSPrimitiveValue::UnitType::Percentage
  40. || unit == CSSPrimitiveValue::UnitType::Ems
  41. || unit == CSSPrimitiveValue::UnitType::Exs
  42. || unit == CSSPrimitiveValue::UnitType::Pixels
  43. || unit == CSSPrimitiveValue::UnitType::Centimeters
  44. || unit == CSSPrimitiveValue::UnitType::Millimeters
  45. || unit == CSSPrimitiveValue::UnitType::Inches
  46. || unit == CSSPrimitiveValue::UnitType::Points
  47. || unit == CSSPrimitiveValue::UnitType::Picas;
  48. }
  49. inline bool isValidLengthUnit(unsigned short type)
  50. {
  51. return isValidLengthUnit(static_cast<CSSPrimitiveValue::UnitType>(type));
  52. }
  53. inline bool canResolveRelativeUnits(const SVGElement* contextElement)
  54. {
  55. return contextElement && contextElement->inShadowIncludingDocument();
  56. }
  57. inline CSSPrimitiveValue::UnitType toCSSUnitType(unsigned short type)
  58. {
  59. ASSERT(isValidLengthUnit(type));
  60. if (type == LengthTypeNumber)
  61. return CSSPrimitiveValue::UnitType::UserUnits;
  62. return static_cast<CSSPrimitiveValue::UnitType>(type);
  63. }
  64. inline SVGLengthType toSVGLengthType(CSSPrimitiveValue::UnitType type)
  65. {
  66. switch (type) {
  67. case CSSPrimitiveValue::UnitType::Unknown:
  68. return LengthTypeUnknown;
  69. case CSSPrimitiveValue::UnitType::UserUnits:
  70. return LengthTypeNumber;
  71. case CSSPrimitiveValue::UnitType::Percentage:
  72. return LengthTypePercentage;
  73. case CSSPrimitiveValue::UnitType::Ems:
  74. return LengthTypeEMS;
  75. case CSSPrimitiveValue::UnitType::Exs:
  76. return LengthTypeEXS;
  77. case CSSPrimitiveValue::UnitType::Pixels:
  78. return LengthTypePX;
  79. case CSSPrimitiveValue::UnitType::Centimeters:
  80. return LengthTypeCM;
  81. case CSSPrimitiveValue::UnitType::Millimeters:
  82. return LengthTypeMM;
  83. case CSSPrimitiveValue::UnitType::Inches:
  84. return LengthTypeIN;
  85. case CSSPrimitiveValue::UnitType::Points:
  86. return LengthTypePT;
  87. case CSSPrimitiveValue::UnitType::Picas:
  88. return LengthTypePC;
  89. default:
  90. return LengthTypeUnknown;
  91. }
  92. }
  93. } // namespace
  94. bool SVGLengthTearOff::hasExposedLengthUnit()
  95. {
  96. CSSPrimitiveValue::UnitType unit = target()->typeWithCalcResolved();
  97. return isValidLengthUnit(unit)
  98. || unit == CSSPrimitiveValue::UnitType::Unknown
  99. || unit == CSSPrimitiveValue::UnitType::UserUnits;
  100. }
  101. SVGLengthType SVGLengthTearOff::unitType()
  102. {
  103. return hasExposedLengthUnit() ? toSVGLengthType(target()->typeWithCalcResolved()) : LengthTypeUnknown;
  104. }
  105. SVGLengthMode SVGLengthTearOff::unitMode()
  106. {
  107. return target()->unitMode();
  108. }
  109. float SVGLengthTearOff::value(ExceptionState& exceptionState)
  110. {
  111. if (target()->isRelative() && !canResolveRelativeUnits(contextElement())) {
  112. exceptionState.throwDOMException(NotSupportedError, "Could not resolve relative length.");
  113. return 0;
  114. }
  115. SVGLengthContext lengthContext(contextElement());
  116. return target()->value(lengthContext);
  117. }
  118. void SVGLengthTearOff::setValue(float value, ExceptionState& exceptionState)
  119. {
  120. if (isImmutable()) {
  121. exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
  122. return;
  123. }
  124. if (target()->isRelative() && !canResolveRelativeUnits(contextElement())) {
  125. exceptionState.throwDOMException(NotSupportedError, "Could not resolve relative length.");
  126. return;
  127. }
  128. SVGLengthContext lengthContext(contextElement());
  129. target()->setValue(value, lengthContext);
  130. commitChange();
  131. }
  132. float SVGLengthTearOff::valueInSpecifiedUnits()
  133. {
  134. return target()->valueInSpecifiedUnits();
  135. }
  136. void SVGLengthTearOff::setValueInSpecifiedUnits(float value, ExceptionState& exceptionState)
  137. {
  138. if (isImmutable()) {
  139. exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
  140. return;
  141. }
  142. target()->setValueInSpecifiedUnits(value);
  143. commitChange();
  144. }
  145. String SVGLengthTearOff::valueAsString()
  146. {
  147. // TODO(shanmuga.m@samsung.com): Not all <length> properties have 0 (with no unit) as the default (lacuna) value, Need to return default value instead of 0
  148. return hasExposedLengthUnit() ? target()->valueAsString() : String::number(0);
  149. }
  150. void SVGLengthTearOff::setValueAsString(const String& str, ExceptionState& exceptionState)
  151. {
  152. if (isImmutable()) {
  153. exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
  154. return;
  155. }
  156. String oldValue = target()->valueAsString();
  157. SVGParsingError status = target()->setValueAsString(str);
  158. if (status == SVGParseStatus::NoError && !hasExposedLengthUnit()) {
  159. target()->setValueAsString(oldValue); // rollback to old value
  160. status = SVGParseStatus::ParsingFailed;
  161. }
  162. if (status != SVGParseStatus::NoError) {
  163. exceptionState.throwDOMException(SyntaxError, "The value provided ('" + str + "') is invalid.");
  164. return;
  165. }
  166. commitChange();
  167. }
  168. void SVGLengthTearOff::newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits, ExceptionState& exceptionState)
  169. {
  170. if (isImmutable()) {
  171. exceptionState.throwDOMException(NoModificationAllowedError, "The object is read-only.");
  172. return;
  173. }
  174. if (!isValidLengthUnit(unitType)) {
  175. exceptionState.throwDOMException(NotSupportedError, "Cannot set value with unknown or invalid units (" + String::number(unitType) + ").");
  176. return;
  177. }
  178. target()->newValueSpecifiedUnits(toCSSUnitType(unitType), valueInSpecifiedUnits);
  179. commitChange();
  180. }
  181. void SVGLengthTearOff::convertToSpecifiedUnits(unsigned short unitType, ExceptionState& exceptionState)
  182. {
  183. if (isImmutable()) {
  184. exceptionState.throwDOMException(NoModificationAllowedError, "The object is read-only.");
  185. return;
  186. }
  187. if (!isValidLengthUnit(unitType)) {
  188. exceptionState.throwDOMException(NotSupportedError, "Cannot convert to unknown or invalid units (" + String::number(unitType) + ").");
  189. return;
  190. }
  191. if ((target()->isRelative() || CSSPrimitiveValue::isRelativeUnit(toCSSUnitType(unitType)))
  192. && !canResolveRelativeUnits(contextElement())) {
  193. exceptionState.throwDOMException(NotSupportedError, "Could not resolve relative length.");
  194. return;
  195. }
  196. SVGLengthContext lengthContext(contextElement());
  197. target()->convertToSpecifiedUnits(toCSSUnitType(unitType), lengthContext);
  198. commitChange();
  199. }
  200. SVGLengthTearOff::SVGLengthTearOff(SVGLength* target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName)
  201. : SVGPropertyTearOff<SVGLength>(target, contextElement, propertyIsAnimVal, attributeName)
  202. {
  203. }
  204. } // namespace blink