44#include " Rules.hpp"
55#include " Helpers.hpp"
66#include " StyleFunction.hpp"
7+ #include " Specificity.hpp"
78
89#include < regex>
910#include < variant>
1011#include < vector>
1112#include < string>
13+ #include < algorithm>
1214#include < folly/dynamic.h>
1315#include < NitroModules/AnyMap.hpp>
1416
@@ -35,6 +37,9 @@ namespace margelo::nitro::cssnitro {
3537 */
3638 std::unordered_map<std::string, AnyValue> mergedStyles;
3739
40+ // Collect all style rules from all classNames
41+ std::vector<HybridStyleRule> allStyleRules;
42+
3843 std::regex whitespace{" \\ s+" };
3944 std::sregex_token_iterator tokenIt (classNames.begin (), classNames.end (),
4045 whitespace, -1 );
@@ -53,43 +58,53 @@ namespace margelo::nitro::cssnitro {
5358
5459 const std::vector<HybridStyleRule> &styleRules = get (*styleIt->second );
5560
56- for (const HybridStyleRule &styleRule: styleRules) {
57- // Skip rule if its media conditions don't pass
58- if (!Rules::testRule (styleRule, get)) {
59- continue ;
60- }
61+ // Add all style rules to the collection
62+ allStyleRules.insert (allStyleRules.end (), styleRules.begin (),
63+ styleRules.end ());
64+ }
65+
66+ // Sort all style rules by specificity (highest specificity first)
67+ std::sort (allStyleRules.begin (), allStyleRules.end (),
68+ [](const HybridStyleRule &a, const HybridStyleRule &b) {
69+ return Specificity::sort (a.s , b.s );
70+ });
6171
62- if (styleRule.d .has_value ()) {
63- const auto declarations = styleRule.d .value ();
64- const auto &dStyles = std::get<0 >(std::get<0 >(declarations));
65- for (const auto &kv: dStyles->getMap ()) {
66- // Only set if key doesn't already exist
67- if (mergedStyles.count (kv.first ) == 0 ) {
68- // if kv.second is an array with "fn" as the first key, resolve it
69- if (dStyles->isArray (kv.first )) {
70- const auto &arr = dStyles->getArray (kv.first );
71- if (!arr.empty () &&
72- std::holds_alternative<std::string>(arr[0 ]) &&
73- std::get<std::string>(arr[0 ]) == " fn" ) {
74- auto result = StyleFunction::resolveStyleFn (
75- arr, get, variableScope);
76-
77- // Skip if resolveStyleFn returns nullptr
78- if (std::holds_alternative<std::monostate>(
79- result)) {
80- continue ;
81- }
82-
83- mergedStyles[kv.first ] = result;
72+ // Now process the sorted style rules
73+ for (const HybridStyleRule &styleRule: allStyleRules) {
74+ // Skip rule if its media conditions don't pass
75+ if (!Rules::testRule (styleRule, get)) {
76+ continue ;
77+ }
78+
79+ if (styleRule.d .has_value ()) {
80+ const auto declarations = styleRule.d .value ();
81+ const auto &dStyles = std::get<0 >(std::get<0 >(declarations));
82+ for (const auto &kv: dStyles->getMap ()) {
83+ // Only set if key doesn't already exist
84+ if (mergedStyles.count (kv.first ) == 0 ) {
85+ // if kv.second is an array with "fn" as the first key, resolve it
86+ if (dStyles->isArray (kv.first )) {
87+ const auto &arr = dStyles->getArray (kv.first );
88+ if (!arr.empty () &&
89+ std::holds_alternative<std::string>(arr[0 ]) &&
90+ std::get<std::string>(arr[0 ]) == " fn" ) {
91+ auto result = StyleFunction::resolveStyleFn (
92+ arr, get, variableScope);
93+
94+ // Skip if resolveStyleFn returns nullptr
95+ if (std::holds_alternative<std::monostate>(
96+ result)) {
8497 continue ;
8598 }
99+
100+ mergedStyles[kv.first ] = result;
101+ continue ;
86102 }
87- mergedStyles[kv.first ] = kv.second ;
88103 }
104+ mergedStyles[kv.first ] = kv.second ;
89105 }
90- // Ignore the other entries for now
91-
92106 }
107+ // Ignore the other entries for now
93108 }
94109 }
95110
0 commit comments