CSS: Support omitting semicolon from last property (#14306)

This commit is contained in:
Sören Nils Kuklau 2022-01-12 10:49:16 +01:00 коммит произвёл GitHub
Родитель bd1232bcb3
Коммит 763bf922d9
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 56 добавлений и 5 удалений

Просмотреть файл

@ -0,0 +1,24 @@
using System.IO;
using NUnit.Framework;
namespace Xamarin.Forms.StyleSheets.UnitTests
{
[TestFixture]
public class StyleParserTests
{
[TestCase("font-size: 10", 1)]
[TestCase("font-size: 10;", 1)]
[TestCase("font-size: 10 background-color: blue", 0)]
[TestCase("font-size: 10; background-color: blue", 2)]
[TestCase("font-size: 10; background-color: blue;", 2)]
public void TestCase(string css, int propertyCount)
{
using (var reader = new StringReader(css))
{
var parser = Style.Parse(new CssReader(reader));
Assert.AreEqual(propertyCount, parser.Declarations.Count);
}
}
}
}

Просмотреть файл

@ -250,6 +250,7 @@
<Compile Include="PathSegmentTests.cs" />
<Compile Include="GeometryTests.cs" />
<Compile Include="ShellParameterPassingTests.cs" />
<Compile Include="StyleSheets\StyleParserTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Xamarin.Forms.Core\Xamarin.Forms.Core.csproj">

Просмотреть файл

@ -21,6 +21,13 @@ namespace Xamarin.Forms.StyleSheets
Style style = new Style();
string propertyName = null, propertyValue = null;
void AddAndClearLastDeclaration()
{
if (!string.IsNullOrEmpty(propertyName) && !string.IsNullOrEmpty(propertyValue))
style.Declarations.Add(propertyName, propertyValue);
propertyName = propertyValue = null;
}
int p;
reader.SkipWhiteSpaces();
bool readingName = true;
@ -35,15 +42,17 @@ namespace Xamarin.Forms.StyleSheets
break;
case ';':
reader.Read();
if (!string.IsNullOrEmpty(propertyName) && !string.IsNullOrEmpty(propertyValue))
style.Declarations.Add(propertyName, propertyValue);
propertyName = propertyValue = null;
AddAndClearLastDeclaration();
readingName = true;
reader.SkipWhiteSpaces();
break;
default:
if ((char)p == stopChar)
{
AddAndClearLastDeclaration();
return style;
}
if (readingName)
{
@ -52,10 +61,22 @@ namespace Xamarin.Forms.StyleSheets
throw new Exception();
}
else
propertyValue = reader.ReadUntil(stopChar, ';', ':');
{
propertyValue = reader.ReadUntil(out var limitedBy, stopChar, ';', ':');
if (limitedBy.HasValue && limitedBy == ':')
{
style.Declarations.Clear();
return style;
}
}
break;
}
}
AddAndClearLastDeclaration();
return style;
}

Просмотреть файл

@ -55,15 +55,20 @@ namespace Xamarin.Forms.StyleSheets
return sb.ToString();
}
public static string ReadUntil(this TextReader reader, params char[] limit)
public static string ReadUntil(this TextReader reader, out char? limitedBy, params char[] limit)
{
limitedBy = null;
var sb = new StringBuilder();
int p;
while ((p = reader.Peek()) > 0)
{
var c = unchecked((char)p);
if (limit != null && limit.Contains(c))
{
limitedBy = c;
break;
}
reader.Read();
sb.Append(c);
}