Bug 1512745 - Use nsWhitespaceTokenizer to ignore leading and trailing whitespace r=longsonr

Length attribute should allow leading and trailing whitespace per SVG2.

Differential Revision: https://phabricator.services.mozilla.com/D23628

--HG--
extra : moz-landing-system : lando
This commit is contained in:
violet 2019-03-27 08:52:33 +00:00
parent b309039307
commit 5cb2a2829c
9 changed files with 83 additions and 19 deletions

View File

@ -37,17 +37,17 @@ const gValidRotate = [
"30.5deg",
"0.5rad",
"auto",
"auto-reverse"
"auto-reverse",
" 10 ",
" 10deg",
"10deg ",
" 10.1 "
];
const gInvalidRotate = [
" 10 ",
" 10deg",
"10 deg",
"10deg ",
"10 rad ",
"aaa",
" 10.1 ",
"aaa"
];
const gValidToBy = [

View File

@ -23,6 +23,7 @@
#include "nsIScriptError.h"
#include "nsLayoutUtils.h"
#include "nsMathUtils.h"
#include "nsWhitespaceTokenizer.h"
#include "SVGAnimationElement.h"
#include "SVGAnimatedPreserveAspectRatio.h"
#include "nsContentUtils.h"
@ -798,4 +799,22 @@ bool SVGContentUtils::ShapeTypeHasNoCorners(const nsIContent* aContent) {
aContent->IsAnyOfSVGElements(nsGkAtoms::circle, nsGkAtoms::ellipse);
}
nsDependentSubstring SVGContentUtils::GetAndEnsureOneToken(
const nsAString& aString, bool& aSuccess) {
nsWhitespaceTokenizerTemplate<nsContentUtils::IsHTMLWhitespace> tokenizer(
aString);
aSuccess = false;
if (!tokenizer.hasMoreTokens()) {
return {};
}
auto token = tokenizer.nextToken();
if (tokenizer.hasMoreTokens()) {
return {};
}
aSuccess = true;
return token;
}
} // namespace mozilla

View File

@ -17,6 +17,7 @@
#include "nsError.h"
#include "nsStringFwd.h"
#include "gfx2DGlue.h"
#include "nsDependentSubstring.h"
class nsIContent;
@ -335,6 +336,14 @@ class SVGContentUtils {
* to have no corners: circle or ellipse
*/
static bool ShapeTypeHasNoCorners(const nsIContent* aContent);
/**
* Return one token in aString, aString may have leading and trailing
* whitespace; aSuccess will be set to false if there is no token or more than
* one token, otherwise it's set to true.
*/
static nsDependentSubstring GetAndEnsureOneToken(const nsAString& aString,
bool& aSuccess);
};
} // namespace mozilla

View File

@ -23,9 +23,16 @@ static SVGAttrTearoffTable<SVGInteger, SVGInteger::DOMAnimatedInteger>
nsresult SVGInteger::SetBaseValueString(const nsAString &aValueAsString,
SVGElement *aSVGElement) {
bool success;
auto token = SVGContentUtils::GetAndEnsureOneToken(aValueAsString, success);
if (!success) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
int32_t value;
if (!SVGContentUtils::ParseInteger(aValueAsString, value)) {
if (!SVGContentUtils::ParseInteger(token, value)) {
return NS_ERROR_DOM_SYNTAX_ERR;
}

View File

@ -32,9 +32,15 @@ void SVGLength::GetValueAsString(nsAString& aValue) const {
}
bool SVGLength::SetValueFromString(const nsAString& aString) {
RangedPtr<const char16_t> iter = SVGContentUtils::GetStartRangedPtr(aString);
const RangedPtr<const char16_t> end =
SVGContentUtils::GetEndRangedPtr(aString);
bool success;
auto token = SVGContentUtils::GetAndEnsureOneToken(aString, success);
if (!success) {
return false;
}
RangedPtr<const char16_t> iter = SVGContentUtils::GetStartRangedPtr(token);
const RangedPtr<const char16_t> end = SVGContentUtils::GetEndRangedPtr(token);
float value;

View File

@ -118,9 +118,15 @@ static void GetAngleValueString(nsAString& aValueAsString, float aValue,
/* static */
bool SVGOrient::GetValueFromString(const nsAString& aString, float& aValue,
uint16_t* aUnitType) {
RangedPtr<const char16_t> iter = SVGContentUtils::GetStartRangedPtr(aString);
const RangedPtr<const char16_t> end =
SVGContentUtils::GetEndRangedPtr(aString);
bool success;
auto token = SVGContentUtils::GetAndEnsureOneToken(aString, success);
if (!success) {
return false;
}
RangedPtr<const char16_t> iter = SVGContentUtils::GetStartRangedPtr(token);
const RangedPtr<const char16_t> end = SVGContentUtils::GetEndRangedPtr(token);
if (!SVGContentUtils::ParseNumber(iter, end, aValue)) {
return false;

View File

@ -85,9 +85,15 @@ static void GetValueString(nsAString& aValueAsString, float aValue,
static bool GetValueFromString(const nsAString& aString, float& aValue,
uint16_t* aUnitType) {
RangedPtr<const char16_t> iter = SVGContentUtils::GetStartRangedPtr(aString);
const RangedPtr<const char16_t> end =
SVGContentUtils::GetEndRangedPtr(aString);
bool success;
auto token = SVGContentUtils::GetAndEnsureOneToken(aString, success);
if (!success) {
return false;
}
RangedPtr<const char16_t> iter = SVGContentUtils::GetStartRangedPtr(token);
const RangedPtr<const char16_t> end = SVGContentUtils::GetEndRangedPtr(token);
if (!SVGContentUtils::ParseNumber(iter, end, aValue)) {
return false;

View File

@ -23,9 +23,15 @@ static SVGAttrTearoffTable<nsSVGNumber2, nsSVGNumber2::DOMAnimatedNumber>
static bool GetValueFromString(const nsAString& aString,
bool aPercentagesAllowed, float& aValue) {
RangedPtr<const char16_t> iter = SVGContentUtils::GetStartRangedPtr(aString);
const RangedPtr<const char16_t> end =
SVGContentUtils::GetEndRangedPtr(aString);
bool success;
auto token = SVGContentUtils::GetAndEnsureOneToken(aString, success);
if (!success) {
return false;
}
RangedPtr<const char16_t> iter = SVGContentUtils::GetStartRangedPtr(token);
const RangedPtr<const char16_t> end = SVGContentUtils::GetEndRangedPtr(token);
if (!SVGContentUtils::ParseNumber(iter, end, aValue)) {
return false;

View File

@ -28,12 +28,17 @@ checkParseOk("1ex", 1, "ex");
checkParseOk("1e1em", 10, "em");
checkParseOk("1E+2", 100);
checkParseOk(".1e-2", 0.001);
checkParseOk(" 10", 10);
checkParseOk("10 ", 10);
checkParseOk(" 10 ", 10);
checkParseOk(" 10em ", 10, "em");
// Fail cases
checkParseFail("1e");
checkParseFail("1 e");
checkParseFail("1 em");
checkParseFail("1ee");
checkParseFail(" 10 20");
function checkParseOk(spec, valueInUnits, units) {
var rect = document.getElementById("rect");