Bug 1446584 - Make SVG use the same definition of whitespace as HTML/CSS r=jwatt
authorRobert Longson <longsonr@gmail.com>
Sun, 18 Mar 2018 07:14:32 +0000
changeset 462259 a8b3ac1e9f25625b6d3e7111c1f53ad36fd2edc2
parent 462258 8b53f6e4c56584b359e5c98eacb653fe78f6b9e7
child 462260 2c4a055ed5d45fe9ca33ae1b450b40e31c9fb8aa
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwatt
bugs1446584
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1446584 - Make SVG use the same definition of whitespace as HTML/CSS r=jwatt
dom/smil/nsSMILParserUtils.cpp
dom/svg/SVGContentUtils.h
dom/svg/SVGLengthList.cpp
dom/svg/SVGMotionSMILPathUtils.cpp
dom/svg/SVGNumberList.cpp
dom/svg/SVGPointList.cpp
dom/svg/SVGPreserveAspectRatio.cpp
dom/svg/SVGStringList.cpp
dom/svg/nsSVGAnimatedTransformList.cpp
dom/svg/nsSVGDataParser.cpp
dom/svg/nsSVGIntegerPair.cpp
dom/svg/nsSVGNumberPair.cpp
dom/svg/nsSVGViewBox.cpp
--- a/dom/smil/nsSMILParserUtils.cpp
+++ b/dom/smil/nsSMILParserUtils.cpp
@@ -32,17 +32,17 @@ const uint32_t MSEC_PER_HOUR = 1000 * 60
 #define REPEAT_PREFIX    NS_LITERAL_STRING("repeat(")
 #define WALLCLOCK_PREFIX NS_LITERAL_STRING("wallclock(")
 
 inline bool
 SkipWhitespace(RangedPtr<const char16_t>& aIter,
                const RangedPtr<const char16_t>& aEnd)
 {
   while (aIter != aEnd) {
-    if (!IsSVGWhitespace(*aIter)) {
+    if (!nsContentUtils::IsHTMLWhitespace(*aIter)) {
       return true;
     }
     ++aIter;
   }
   return false;
 }
 
 inline bool
@@ -274,17 +274,17 @@ MoveToNextToken(RangedPtr<const char16_t
                 const RangedPtr<const char16_t>& aEnd,
                 bool aBreakOnDot,
                 bool& aIsAnyCharEscaped)
 {
   aIsAnyCharEscaped = false;
 
   bool isCurrentCharEscaped = false;
 
-  while (aIter != aEnd && !IsSVGWhitespace(*aIter)) {
+  while (aIter != aEnd && !nsContentUtils::IsHTMLWhitespace(*aIter)) {
     if (isCurrentCharEscaped) {
       isCurrentCharEscaped = false;
     } else {
       if (*aIter == '+' || *aIter == '-' ||
           (aBreakOnDot && *aIter == '.')) {
         break;
       }
       if (*aIter == '\\') {
@@ -438,43 +438,44 @@ const nsDependentSubstring
 nsSMILParserUtils::TrimWhitespace(const nsAString& aString)
 {
   nsAString::const_iterator start, end;
 
   aString.BeginReading(start);
   aString.EndReading(end);
 
   // Skip whitespace characters at the beginning
-  while (start != end && IsSVGWhitespace(*start)) {
+  while (start != end && nsContentUtils::IsHTMLWhitespace(*start)) {
     ++start;
   }
 
   // Skip whitespace characters at the end.
   while (end != start) {
     --end;
 
-    if (!IsSVGWhitespace(*end)) {
+    if (!nsContentUtils::IsHTMLWhitespace(*end)) {
       // Step back to the last non-whitespace character.
       ++end;
 
       break;
     }
   }
 
   return Substring(start, end);
 }
 
 bool
 nsSMILParserUtils::ParseKeySplines(const nsAString& aSpec,
                                    FallibleTArray<nsSMILKeySpline>& aKeySplines)
 {
-  nsCharSeparatedTokenizerTemplate<IsSVGWhitespace> controlPointTokenizer(aSpec, ';');
+  nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
+    controlPointTokenizer(aSpec, ';');
   while (controlPointTokenizer.hasMoreTokens()) {
 
-    nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
+    nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
       tokenizer(controlPointTokenizer.nextToken(), ',',
                 nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
 
     double values[4];
     for (int i = 0 ; i < 4; i++) {
       if (!tokenizer.hasMoreTokens() ||
           !SVGContentUtils::ParseNumber(tokenizer.nextToken(), values[i]) ||
           values[i] > 1.0 || values[i] < 0.0) {
@@ -495,17 +496,18 @@ nsSMILParserUtils::ParseKeySplines(const
   return !aKeySplines.IsEmpty();
 }
 
 bool
 nsSMILParserUtils::ParseSemicolonDelimitedProgressList(const nsAString& aSpec,
                                                        bool aNonDecreasing,
                                                        FallibleTArray<double>& aArray)
 {
-  nsCharSeparatedTokenizerTemplate<IsSVGWhitespace> tokenizer(aSpec, ';');
+  nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
+    tokenizer(aSpec, ';');
 
   double previousValue = -1.0;
 
   while (tokenizer.hasMoreTokens()) {
     double value;
     if (!SVGContentUtils::ParseNumber(tokenizer.nextToken(), value)) {
       return false;
     }
@@ -574,17 +576,18 @@ nsSMILParserUtils::ParseValues(const nsA
                               &aValuesArray, &aPreventCachingOfSandwich);
   return ParseValuesGeneric(aSpec, valueParser);
 }
 
 bool
 nsSMILParserUtils::ParseValuesGeneric(const nsAString& aSpec,
                                       GenericValueParser& aParser)
 {
-  nsCharSeparatedTokenizerTemplate<IsSVGWhitespace> tokenizer(aSpec, ';');
+  nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
+    tokenizer(aSpec, ';');
   if (!tokenizer.hasMoreTokens()) { // Empty list
     return false;
   }
 
   while (tokenizer.hasMoreTokens()) {
     if (!aParser.Parse(tokenizer.nextToken())) {
       return false;
     }
@@ -660,17 +663,17 @@ nsSMILParserUtils::CheckForNegativeNumbe
 {
   int32_t absValLocation = -1;
 
   RangedPtr<const char16_t> start(SVGContentUtils::GetStartRangedPtr(aStr));
   RangedPtr<const char16_t> iter = start;
   RangedPtr<const char16_t> end(SVGContentUtils::GetEndRangedPtr(aStr));
 
   // Skip initial whitespace
-  while (iter != end && IsSVGWhitespace(*iter)) {
+  while (iter != end && nsContentUtils::IsHTMLWhitespace(*iter)) {
     ++iter;
   }
 
   // Check for dash
   if (iter != end && *iter == '-') {
     ++iter;
     // Check for numeric character
     if (iter != end && SVGContentUtils::IsDigit(*iter)) {
--- a/dom/svg/SVGContentUtils.h
+++ b/dom/svg/SVGContentUtils.h
@@ -63,30 +63,16 @@ class SVGViewportElement;
  * does not include any transforms due to the 'transform' attribute.
  */
 enum SVGTransformTypes {
    eAllTransforms,
    eUserSpaceToParent,
    eChildToUserSpace
 };
 
-inline bool
-IsSVGWhitespace(char aChar)
-{
-  return aChar == '\x20' || aChar == '\x9' ||
-         aChar == '\xD'  || aChar == '\xA';
-}
-
-inline bool
-IsSVGWhitespace(char16_t aChar)
-{
-  return aChar == char16_t('\x20') || aChar == char16_t('\x9') ||
-         aChar == char16_t('\xD')  || aChar == char16_t('\xA');
-}
-
 /**
  * Functions generally used by SVG Content classes. Functions here
  * should not generally depend on layout methods/classes e.g. nsSVGUtils
  */
 class SVGContentUtils
 {
 public:
   typedef mozilla::gfx::Float Float;
--- a/dom/svg/SVGLengthList.cpp
+++ b/dom/svg/SVGLengthList.cpp
@@ -40,17 +40,17 @@ SVGLengthList::GetValueAsString(nsAStrin
   }
 }
 
 nsresult
 SVGLengthList::SetValueFromString(const nsAString& aValue)
 {
   SVGLengthList temp;
 
-  nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
+  nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
     tokenizer(aValue, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
 
   while (tokenizer.hasMoreTokens()) {
     SVGLength length;
     if (!length.SetValueFromString(tokenizer.nextToken())) {
       return NS_ERROR_DOM_SYNTAX_ERR;
     }
     if (!temp.AppendItem(length)) {
--- a/dom/svg/SVGMotionSMILPathUtils.cpp
+++ b/dom/svg/SVGMotionSMILPathUtils.cpp
@@ -89,17 +89,17 @@ SVGMotionSMILPathUtils::PathGenerator::G
 //----------------------------------------------------------------------
 // Helper / protected methods
 
 bool
 SVGMotionSMILPathUtils::PathGenerator::
   ParseCoordinatePair(const nsAString& aCoordPairStr,
                       float& aXVal, float& aYVal)
 {
-  nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
+  nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
     tokenizer(aCoordPairStr, ',',
               nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
 
   SVGLength x, y;
 
   if (!tokenizer.hasMoreTokens() ||
       !x.SetValueFromString(tokenizer.nextToken())) {
     return false;
--- a/dom/svg/SVGNumberList.cpp
+++ b/dom/svg/SVGNumberList.cpp
@@ -43,17 +43,17 @@ SVGNumberList::GetValueAsString(nsAStrin
   }
 }
 
 nsresult
 SVGNumberList::SetValueFromString(const nsAString& aValue)
 {
   SVGNumberList temp;
 
-  nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
+  nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
     tokenizer(aValue, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
 
   while (tokenizer.hasMoreTokens()) {
     float num;
     if (!SVGContentUtils::ParseNumber(tokenizer.nextToken(), num)) {
       return NS_ERROR_DOM_SYNTAX_ERR;
     }
     if (!temp.AppendItem(num)) {
--- a/dom/svg/SVGPointList.cpp
+++ b/dom/svg/SVGPointList.cpp
@@ -49,17 +49,17 @@ SVGPointList::SetValueFromString(const n
   // encountered, so we must call CopyFrom even if an error occurs. We still
   // want to throw any error code from setAttribute if there's a problem
   // though, so we must take care to return any error code.
 
   nsresult rv = NS_OK;
 
   SVGPointList temp;
 
-  nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
+  nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
     tokenizer(aValue, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
 
   while (tokenizer.hasMoreTokens()) {
 
     const nsAString& token = tokenizer.nextToken();
 
     RangedPtr<const char16_t> iter =
       SVGContentUtils::GetStartRangedPtr(token);
--- a/dom/svg/SVGPreserveAspectRatio.cpp
+++ b/dom/svg/SVGPreserveAspectRatio.cpp
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "SVGPreserveAspectRatio.h"
 
 #include "mozilla/dom/SVGPreserveAspectRatioBinding.h"
+#include "nsContentUtils.h"
 #include "nsWhitespaceTokenizer.h"
 #include "SVGAnimatedPreserveAspectRatio.h"
 
 using namespace mozilla;
 using namespace dom;
 using namespace SVGPreserveAspectRatioBinding;
 
 NS_SVG_VAL_IMPL_CYCLE_COLLECTION_WRAPPERCACHED(DOMSVGPreserveAspectRatio, mSVGElement)
@@ -53,17 +54,18 @@ GetMeetOrSliceForString(const nsAString 
 
   return SVG_MEETORSLICE_UNKNOWN;
 }
 
 /* static */ nsresult
 SVGPreserveAspectRatio::FromString(const nsAString& aString,
                                    SVGPreserveAspectRatio* aValue)
 {
-  nsWhitespaceTokenizerTemplate<IsSVGWhitespace> tokenizer(aString);
+  nsWhitespaceTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
+    tokenizer(aString);
   if (tokenizer.whitespaceBeforeFirstToken() ||
       !tokenizer.hasMoreTokens()) {
     return NS_ERROR_DOM_SYNTAX_ERR;
   }
   const nsAString &token = tokenizer.nextToken();
 
   nsresult rv;
   SVGPreserveAspectRatio val;
--- a/dom/svg/SVGStringList.cpp
+++ b/dom/svg/SVGStringList.cpp
@@ -40,29 +40,30 @@ SVGStringList::GetValue(nsAString& aValu
 }
 
 nsresult
 SVGStringList::SetValue(const nsAString& aValue)
 {
   SVGStringList temp;
 
   if (mIsCommaSeparated) {
-    nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
+    nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
       tokenizer(aValue, ',');
 
     while (tokenizer.hasMoreTokens()) {
       if (!temp.AppendItem(tokenizer.nextToken())) {
         return NS_ERROR_OUT_OF_MEMORY;
       }
     }
     if (tokenizer.separatorAfterCurrentToken()) {
       return NS_ERROR_DOM_SYNTAX_ERR; // trailing comma
     }
   } else {
-    nsWhitespaceTokenizerTemplate<IsSVGWhitespace> tokenizer(aValue);
+    nsWhitespaceTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
+      tokenizer(aValue);
 
     while (tokenizer.hasMoreTokens()) {
       if (!temp.AppendItem(tokenizer.nextToken())) {
         return NS_ERROR_OUT_OF_MEMORY;
       }
     }
   }
 
--- a/dom/svg/nsSVGAnimatedTransformList.cpp
+++ b/dom/svg/nsSVGAnimatedTransformList.cpp
@@ -265,17 +265,17 @@ nsSVGAnimatedTransformList::SMILAnimated
 }
 
 int32_t
 nsSVGAnimatedTransformList::SMILAnimatedTransformList::ParseParameterList(
   const nsAString& aSpec,
   float* aVars,
   int32_t aNVars)
 {
-  nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
+  nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
     tokenizer(aSpec, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
 
   int numArgsFound = 0;
 
   while (tokenizer.hasMoreTokens()) {
     float f;
     if (!SVGContentUtils::ParseNumber(tokenizer.nextToken(), f)) {
       return -1;
--- a/dom/svg/nsSVGDataParser.cpp
+++ b/dom/svg/nsSVGDataParser.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsSVGDataParser.h"
+#include "nsContentUtils.h"
 #include "SVGContentUtils.h"
 
 nsSVGDataParser::nsSVGDataParser(const nsAString& aValue)
   : mIter(SVGContentUtils::GetStartRangedPtr(aValue)),
     mEnd(SVGContentUtils::GetEndRangedPtr(aValue))
 {
 }
 
@@ -26,15 +27,15 @@ nsSVGDataParser::SkipCommaWsp()
   ++mIter;
   return SkipWsp();
 }
 
 bool
 nsSVGDataParser::SkipWsp()
 {
   while (mIter != mEnd) {
-    if (!IsSVGWhitespace(*mIter)) {
+    if (!nsContentUtils::IsHTMLWhitespace(*mIter)) {
       return true;
     }
     ++mIter;
   }
   return false;
 }
--- a/dom/svg/nsSVGIntegerPair.cpp
+++ b/dom/svg/nsSVGIntegerPair.cpp
@@ -22,19 +22,18 @@ static nsSVGAttrTearoffTable<nsSVGIntege
   sSVGSecondAnimatedIntegerTearoffTable;
 
 /* Implementation */
 
 static nsresult
 ParseIntegerOptionalInteger(const nsAString& aValue,
                             int32_t aValues[2])
 {
-  nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
-    tokenizer(aValue, ',',
-              nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
+  nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
+    tokenizer(aValue, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
   if (tokenizer.whitespaceBeforeFirstToken()) {
     return NS_ERROR_DOM_SYNTAX_ERR;
   }
 
   uint32_t i;
   for (i = 0; i < 2 && tokenizer.hasMoreTokens(); ++i) {
     if (!SVGContentUtils::ParseInteger(tokenizer.nextToken(), aValues[i])) {
       return NS_ERROR_DOM_SYNTAX_ERR;
--- a/dom/svg/nsSVGNumberPair.cpp
+++ b/dom/svg/nsSVGNumberPair.cpp
@@ -18,17 +18,17 @@ static nsSVGAttrTearoffTable<nsSVGNumber
   sSVGFirstAnimatedNumberTearoffTable;
 static nsSVGAttrTearoffTable<nsSVGNumberPair, nsSVGNumberPair::DOMAnimatedNumber>
   sSVGSecondAnimatedNumberTearoffTable;
 
 static nsresult
 ParseNumberOptionalNumber(const nsAString& aValue,
                           float aValues[2])
 {
-  nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
+  nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
     tokenizer(aValue, ',',
               nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
   if (tokenizer.whitespaceBeforeFirstToken()) {
     return NS_ERROR_DOM_SYNTAX_ERR;
   }
 
   uint32_t i;
   for (i = 0; i < 2 && tokenizer.hasMoreTokens(); ++i) {
--- a/dom/svg/nsSVGViewBox.cpp
+++ b/dom/svg/nsSVGViewBox.cpp
@@ -35,19 +35,18 @@ nsSVGViewBoxRect::operator==(const nsSVG
 /* static */ nsresult
 nsSVGViewBoxRect::FromString(const nsAString& aStr, nsSVGViewBoxRect *aViewBox)
 {
   if (aStr.EqualsLiteral("none")) {
     aViewBox->none = true;
     return NS_OK;
   }
 
-  nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
-  tokenizer(aStr, ',',
-            nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
+  nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
+    tokenizer(aStr, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
   float vals[NUM_VIEWBOX_COMPONENTS];
   uint32_t i;
   for (i = 0; i < NUM_VIEWBOX_COMPONENTS && tokenizer.hasMoreTokens(); ++i) {
     if (!SVGContentUtils::ParseNumber(tokenizer.nextToken(), vals[i])) {
       return NS_ERROR_DOM_SYNTAX_ERR;
     }
   }