From 8b32f26b9f8b9589a686affd5c71073f596fe735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sat, 4 Jul 2026 01:25:42 -0300 Subject: [PATCH] Some extra optimizations to CSS selector. --- include/eepp/ui/css/stylesheetstyle.hpp | 2 +- src/eepp/ui/css/stylesheetselectorrule.cpp | 62 ++++++++++++---------- src/eepp/ui/css/stylesheetstyle.cpp | 8 --- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/include/eepp/ui/css/stylesheetstyle.hpp b/include/eepp/ui/css/stylesheetstyle.hpp index e63f6668a..4ad4ebe33 100644 --- a/include/eepp/ui/css/stylesheetstyle.hpp +++ b/include/eepp/ui/css/stylesheetstyle.hpp @@ -55,7 +55,7 @@ class EE_API StyleSheetStyle { void setVariable( const StyleSheetVariable& variable ); - bool isMediaValid() const; + bool isMediaValid() const { return !mMediaQueryList || mMediaQueryList->isUsed(); } const MediaQueryList::ptr& getMediaQueryList() const; diff --git a/src/eepp/ui/css/stylesheetselectorrule.cpp b/src/eepp/ui/css/stylesheetselectorrule.cpp index 51018a3e9..5626ce7da 100644 --- a/src/eepp/ui/css/stylesheetselectorrule.cpp +++ b/src/eepp/ui/css/stylesheetselectorrule.cpp @@ -45,7 +45,30 @@ static bool isStructuralPseudoClass( const std::string& pseudoClass ) { } static bool isDataAttributeName( std::string_view name ) { - return String::istartsWith( String::trim( name ), "data-" ); + return String::istartsWith( name, "data-" ); +} + +static bool containsWord( const std::string& string, const std::string& word ) { + size_t pos = 0; + while ( pos < string.size() ) { + while ( pos < string.size() && string[pos] == ' ' ) + pos++; + + size_t end = string.find( ' ', pos ); + if ( end == std::string::npos ) + end = string.size(); + + if ( word.size() == end - pos && string.compare( pos, word.size(), word ) == 0 ) + return true; + + pos = end + 1; + } + return false; +} + +static bool startsWithDashMatch( const std::string& string, const std::string& prefix ) { + return string == prefix || ( string.size() > prefix.size() && string[prefix.size()] == '-' && + string.compare( 0, prefix.size(), prefix ) == 0 ); } StyleSheetSelectorRule::PseudoClasses @@ -311,20 +334,18 @@ bool StyleSheetSelectorRule::matches( UIWidget* element, const bool& applyPseudo } } - const std::vector& elClasses = element->getStyleSheetClasses(); - if ( !mClasses.empty() && !elClasses.empty() ) { - bool hasClasses = true; + if ( !mClasses.empty() ) { + const std::vector& elClasses = element->getStyleSheetClasses(); + if ( elClasses.empty() ) + return false; for ( const auto& cls : mClasses ) { if ( std::find( elClasses.begin(), elClasses.end(), cls ) == elClasses.end() ) { - hasClasses = false; - break; + return false; } } - if ( hasClasses ) { - flags |= Class; - } + flags |= Class; } if ( !mAttributeSelectors.empty() ) { @@ -366,16 +387,14 @@ bool StyleSheetSelectorRule::matches( UIWidget* element, const bool& applyPseudo return false; break; case AttributeOperator::ContainsWord: { // ~= (Space-separated word check) - auto words = String::split( *elVal, ' ', true ); - if ( std::find( words.begin(), words.end(), attr.value ) == words.end() ) { + if ( !containsWord( *elVal, attr.value ) ) { return false; } break; } case AttributeOperator::StartsWithDash: // |= (Exact match or starts with value // + "-") - if ( *elVal != attr.value && - !String::startsWith( *elVal, attr.value + "-" ) ) { + if ( !startsWithDashMatch( *elVal, attr.value ) ) { return false; } break; @@ -389,21 +408,10 @@ bool StyleSheetSelectorRule::matches( UIWidget* element, const bool& applyPseudo } if ( applyPseudo ) { - if ( mPseudoClasses && element->getStyleSheetPseudoClasses() ) { - bool hasPseudoClasses = true; - - for ( Uint32 i = 0; i < PseudoClassesTotal; i++ ) { - Uint32 pcls = ( 1 << i ); - if ( ( mPseudoClasses & pcls ) && - !( element->getStyleSheetPseudoClasses() & pcls ) ) { - hasPseudoClasses = false; - break; - } - } - - if ( hasPseudoClasses ) { + if ( mPseudoClasses ) { + const Uint32 elementPseudoClasses = element->getStyleSheetPseudoClasses(); + if ( ( elementPseudoClasses & mPseudoClasses ) == mPseudoClasses ) flags |= PseudoClass; - } } if ( !mStructuralSelectors.empty() ) { diff --git a/src/eepp/ui/css/stylesheetstyle.cpp b/src/eepp/ui/css/stylesheetstyle.cpp index 36d15bf9c..6b3d04fe3 100644 --- a/src/eepp/ui/css/stylesheetstyle.cpp +++ b/src/eepp/ui/css/stylesheetstyle.cpp @@ -204,14 +204,6 @@ void StyleSheetStyle::setVariable( const StyleSheetVariable& variable ) { mVariables[variable.getNameHash()].setSpecificity( mSelector.getSpecificity() ); } -bool StyleSheetStyle::isMediaValid() const { - if ( !mMediaQueryList ) { - return true; - } - - return mMediaQueryList->isUsed(); -} - const MediaQueryList::ptr& StyleSheetStyle::getMediaQueryList() const { return mMediaQueryList; }