@@ -45,7 +45,30 @@ static bool isStructuralPseudoClass( const std::string& pseudoClass ) {
4545}
4646
4747static bool isDataAttributeName ( std::string_view name ) {
48- return String::istartsWith ( String::trim ( name ), " data-" );
48+ return String::istartsWith ( name, " data-" );
49+ }
50+
51+ static bool containsWord ( const std::string& string, const std::string& word ) {
52+ size_t pos = 0 ;
53+ while ( pos < string.size () ) {
54+ while ( pos < string.size () && string[pos] == ' ' )
55+ pos++;
56+
57+ size_t end = string.find ( ' ' , pos );
58+ if ( end == std::string::npos )
59+ end = string.size ();
60+
61+ if ( word.size () == end - pos && string.compare ( pos, word.size (), word ) == 0 )
62+ return true ;
63+
64+ pos = end + 1 ;
65+ }
66+ return false ;
67+ }
68+
69+ static bool startsWithDashMatch ( const std::string& string, const std::string& prefix ) {
70+ return string == prefix || ( string.size () > prefix.size () && string[prefix.size ()] == ' -' &&
71+ string.compare ( 0 , prefix.size (), prefix ) == 0 );
4972}
5073
5174StyleSheetSelectorRule::PseudoClasses
@@ -311,20 +334,18 @@ bool StyleSheetSelectorRule::matches( UIWidget* element, const bool& applyPseudo
311334 }
312335 }
313336
314- const std::vector<std::string>& elClasses = element->getStyleSheetClasses ();
315- if ( !mClasses .empty () && !elClasses.empty () ) {
316- bool hasClasses = true ;
337+ if ( !mClasses .empty () ) {
338+ const std::vector<std::string>& elClasses = element->getStyleSheetClasses ();
339+ if ( elClasses.empty () )
340+ return false ;
317341
318342 for ( const auto & cls : mClasses ) {
319343 if ( std::find ( elClasses.begin (), elClasses.end (), cls ) == elClasses.end () ) {
320- hasClasses = false ;
321- break ;
344+ return false ;
322345 }
323346 }
324347
325- if ( hasClasses ) {
326- flags |= Class;
327- }
348+ flags |= Class;
328349 }
329350
330351 if ( !mAttributeSelectors .empty () ) {
@@ -366,16 +387,14 @@ bool StyleSheetSelectorRule::matches( UIWidget* element, const bool& applyPseudo
366387 return false ;
367388 break ;
368389 case AttributeOperator::ContainsWord: { // ~= (Space-separated word check)
369- auto words = String::split ( *elVal, ' ' , true );
370- if ( std::find ( words.begin (), words.end (), attr.value ) == words.end () ) {
390+ if ( !containsWord ( *elVal, attr.value ) ) {
371391 return false ;
372392 }
373393 break ;
374394 }
375395 case AttributeOperator::StartsWithDash: // |= (Exact match or starts with value
376396 // + "-")
377- if ( *elVal != attr.value &&
378- !String::startsWith ( *elVal, attr.value + " -" ) ) {
397+ if ( !startsWithDashMatch ( *elVal, attr.value ) ) {
379398 return false ;
380399 }
381400 break ;
@@ -389,21 +408,10 @@ bool StyleSheetSelectorRule::matches( UIWidget* element, const bool& applyPseudo
389408 }
390409
391410 if ( applyPseudo ) {
392- if ( mPseudoClasses && element->getStyleSheetPseudoClasses () ) {
393- bool hasPseudoClasses = true ;
394-
395- for ( Uint32 i = 0 ; i < PseudoClassesTotal; i++ ) {
396- Uint32 pcls = ( 1 << i );
397- if ( ( mPseudoClasses & pcls ) &&
398- !( element->getStyleSheetPseudoClasses () & pcls ) ) {
399- hasPseudoClasses = false ;
400- break ;
401- }
402- }
403-
404- if ( hasPseudoClasses ) {
411+ if ( mPseudoClasses ) {
412+ const Uint32 elementPseudoClasses = element->getStyleSheetPseudoClasses ();
413+ if ( ( elementPseudoClasses & mPseudoClasses ) == mPseudoClasses )
405414 flags |= PseudoClass;
406- }
407415 }
408416
409417 if ( !mStructuralSelectors .empty () ) {
0 commit comments