mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-08-14 13:15:14 +03:00
Fix in CSS properties parser when comments were between and inside properties.
This commit is contained in:
@@ -22,9 +22,7 @@ class EE_API StyleSheetPropertiesParser {
|
||||
const StyleSheetVariables& getVariables() const;
|
||||
|
||||
protected:
|
||||
enum ReadState { ReadingPropertyName, ReadingPropertyValue, ReadingComment };
|
||||
|
||||
ReadState mPrevRs{ ReadingPropertyName };
|
||||
enum ReadState { ReadingPropertyName, ReadingPropertyValue };
|
||||
|
||||
StyleSheetProperties mProperties;
|
||||
StyleSheetVariables mVariables;
|
||||
@@ -35,8 +33,6 @@ class EE_API StyleSheetPropertiesParser {
|
||||
int readPropertyValue( ReadState& rs, std::size_t pos, std::string& buffer,
|
||||
std::string_view str );
|
||||
|
||||
int readComment( ReadState& rs, std::size_t pos, std::string& buffer, std::string_view str );
|
||||
|
||||
void addProperty( std::string name, std::string value );
|
||||
};
|
||||
|
||||
|
||||
@@ -6,6 +6,21 @@ using namespace EE::UI;
|
||||
|
||||
namespace EE { namespace UI { namespace CSS {
|
||||
|
||||
static std::size_t skipComment( std::string_view str, std::size_t pos ) {
|
||||
pos += 2;
|
||||
while ( pos + 1 < str.size() ) {
|
||||
if ( str[pos] == '*' && str[pos + 1] == '/' )
|
||||
return pos + 2;
|
||||
pos++;
|
||||
}
|
||||
return str.size();
|
||||
}
|
||||
|
||||
static void appendCommentWhitespace( std::string& buffer ) {
|
||||
if ( !buffer.empty() && buffer.back() != ' ' )
|
||||
buffer += ' ';
|
||||
}
|
||||
|
||||
StyleSheetPropertiesParser::StyleSheetPropertiesParser( std::string_view propsstr ) {
|
||||
parse( propsstr );
|
||||
}
|
||||
@@ -22,7 +37,6 @@ void StyleSheetPropertiesParser::parse( std::string_view propsstr ) {
|
||||
mProperties.clear();
|
||||
mVariables.clear();
|
||||
ReadState rs = ReadingPropertyName;
|
||||
mPrevRs = rs;
|
||||
std::size_t pos = 0;
|
||||
std::string buffer;
|
||||
|
||||
@@ -36,9 +50,6 @@ void StyleSheetPropertiesParser::parse( std::string_view propsstr ) {
|
||||
pos = readPropertyValue( rs, pos, buffer, propsstr );
|
||||
break;
|
||||
}
|
||||
case ReadingComment: {
|
||||
pos = readComment( rs, pos, buffer, propsstr );
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -48,13 +59,13 @@ void StyleSheetPropertiesParser::parse( std::string_view propsstr ) {
|
||||
int StyleSheetPropertiesParser::readPropertyName( StyleSheetPropertiesParser::ReadState& rs,
|
||||
std::size_t pos, std::string& buffer,
|
||||
std::string_view str ) {
|
||||
mPrevRs = rs;
|
||||
buffer.clear();
|
||||
|
||||
while ( pos < str.size() ) {
|
||||
if ( str[pos] == '/' && str.size() > pos + 1 && str[pos + 1] == '*' ) {
|
||||
rs = ReadingComment;
|
||||
return pos;
|
||||
appendCommentWhitespace( buffer );
|
||||
pos = skipComment( str, pos );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( str[pos] == ':' ) {
|
||||
@@ -78,8 +89,6 @@ int StyleSheetPropertiesParser::readPropertyValue( StyleSheetPropertiesParser::R
|
||||
|
||||
buffer.clear();
|
||||
|
||||
mPrevRs = rs;
|
||||
|
||||
bool inDoubleQuote = false;
|
||||
bool inSingleQuote = false;
|
||||
int nestedParenthesis = 0;
|
||||
@@ -89,8 +98,9 @@ int StyleSheetPropertiesParser::readPropertyValue( StyleSheetPropertiesParser::R
|
||||
// Ensure we aren't parsing comments inside strings
|
||||
if ( str[pos] == '/' && str.size() > pos + 1 && str[pos + 1] == '*' && !inDoubleQuote &&
|
||||
!inSingleQuote ) {
|
||||
rs = ReadingComment;
|
||||
return pos;
|
||||
appendCommentWhitespace( buffer );
|
||||
pos = skipComment( str, pos );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Only terminate property parsing on ';' if we are outside of quotes and parentheses
|
||||
@@ -118,36 +128,11 @@ int StyleSheetPropertiesParser::readPropertyValue( StyleSheetPropertiesParser::R
|
||||
|
||||
pos++;
|
||||
|
||||
if ( pos == str.size() ) {
|
||||
rs = ReadingPropertyName;
|
||||
|
||||
addProperty( propName, buffer );
|
||||
|
||||
return pos + 1;
|
||||
}
|
||||
|
||||
prevChar = str[pos - 1];
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
int StyleSheetPropertiesParser::readComment( StyleSheetPropertiesParser::ReadState& rs,
|
||||
std::size_t pos, std::string& buffer,
|
||||
std::string_view str ) {
|
||||
buffer.clear();
|
||||
|
||||
while ( pos < str.size() ) {
|
||||
if ( str[pos] == '*' && str.size() > pos + 1 && str[pos + 1] == '/' ) {
|
||||
rs = mPrevRs;
|
||||
return pos + 2;
|
||||
}
|
||||
|
||||
buffer += str[pos];
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
rs = ReadingPropertyName;
|
||||
addProperty( propName, buffer );
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <eepp/system/filesystem.hpp>
|
||||
#include <eepp/ui/css/stylesheet.hpp>
|
||||
#include <eepp/ui/css/stylesheetlength.hpp>
|
||||
#include <eepp/ui/css/stylesheetpropertiesparser.hpp>
|
||||
#include <eepp/ui/css/stylesheetproperty.hpp>
|
||||
#include <eepp/ui/css/stylesheetpropertyanimation.hpp>
|
||||
#include <eepp/ui/css/stylesheetspecification.hpp>
|
||||
@@ -29,6 +30,37 @@ using namespace EE::UI::CSS;
|
||||
using namespace EE::Scene;
|
||||
using namespace EE::Graphics;
|
||||
|
||||
UTEST( CSSParser, CommentsPreserveDeclarationContext ) {
|
||||
StyleSheetPropertiesParser parser( R"css(
|
||||
color /* before colon */ : red;
|
||||
margin: 1px /* between values */ 2px;
|
||||
font-family: "A/* literal */B";
|
||||
/* between declarations */ width: 140px;
|
||||
line-height: 40px !important /* final declaration without semicolon */
|
||||
)css" );
|
||||
const auto& properties = parser.getProperties();
|
||||
|
||||
auto lineHeight = properties.find( static_cast<Uint32>( PropertyId::LineHeight ) );
|
||||
auto color = properties.find( static_cast<Uint32>( PropertyId::Color ) );
|
||||
auto marginTop = properties.find( static_cast<Uint32>( PropertyId::MarginTop ) );
|
||||
auto marginRight = properties.find( static_cast<Uint32>( PropertyId::MarginRight ) );
|
||||
auto fontFamily = properties.find( static_cast<Uint32>( PropertyId::FontFamily ) );
|
||||
auto width = properties.find( static_cast<Uint32>( PropertyId::Width ) );
|
||||
|
||||
ASSERT_TRUE( lineHeight != properties.end() );
|
||||
ASSERT_TRUE( color != properties.end() );
|
||||
ASSERT_TRUE( marginTop != properties.end() );
|
||||
ASSERT_TRUE( marginRight != properties.end() );
|
||||
ASSERT_TRUE( fontFamily != properties.end() );
|
||||
ASSERT_TRUE( width != properties.end() );
|
||||
EXPECT_TRUE( lineHeight->second.getValue() == "40px" );
|
||||
EXPECT_TRUE( color->second.getValue() == "red" );
|
||||
EXPECT_TRUE( marginTop->second.getValue() == "1px" );
|
||||
EXPECT_TRUE( marginRight->second.getValue() == "2px" );
|
||||
EXPECT_TRUE( fontFamily->second.getValue().find( "/* literal */" ) != std::string::npos );
|
||||
EXPECT_TRUE( width->second.getValue() == "140px" );
|
||||
}
|
||||
|
||||
UTEST( CSSInheritance, HtmlXmlLoadingInheritance ) {
|
||||
UIApplication app(
|
||||
WindowSettings( 800, 600, "eepp - CSS Inheritance Test", WindowStyle::Default,
|
||||
|
||||
Reference in New Issue
Block a user