Skip to content

Commit b0f5bc2

Browse files
committed
Ensure correct output order of compound selectors
Fixes #3084
1 parent 9515008 commit b0f5bc2

File tree

3 files changed

+21
-0
lines changed

3 files changed

+21
-0
lines changed

src/ast_selectors.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -940,6 +940,16 @@ namespace Sass {
940940

941941
}
942942

943+
bool cmpSimpleSelectors(SimpleSelector* a, SimpleSelector* b)
944+
{
945+
return (a->getSortOrder() < b->getSortOrder());
946+
}
947+
948+
void CompoundSelector::sortChildren()
949+
{
950+
std::sort(begin(), end(), cmpSimpleSelectors);
951+
}
952+
943953
/* better return sass::vector? only - is empty container anyway? */
944954
SelectorList* ComplexSelector::resolve_parent_refs(SelectorStack pstack, Backtraces& traces, bool implicit_parent)
945955
{

src/ast_selectors.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ namespace Sass {
9999
HASH_PROPERTY(bool, has_ns)
100100
public:
101101
SimpleSelector(SourceSpan pstate, sass::string n = "");
102+
// ordering within parent (peudos go last)
103+
virtual int getSortOrder() const = 0;
102104
virtual sass::string ns_name() const;
103105
size_t hash() const override;
104106
virtual bool empty() const;
@@ -147,6 +149,7 @@ namespace Sass {
147149
class PlaceholderSelector final : public SimpleSelector {
148150
public:
149151
PlaceholderSelector(SourceSpan pstate, sass::string n);
152+
int getSortOrder() const override final { return 0; }
150153
bool isInvisible() const override { return true; }
151154
virtual unsigned long specificity() const override;
152155
virtual bool has_placeholder() override;
@@ -162,6 +165,7 @@ namespace Sass {
162165
class TypeSelector final : public SimpleSelector {
163166
public:
164167
TypeSelector(SourceSpan pstate, sass::string n);
168+
int getSortOrder() const override final { return 1; }
165169
virtual unsigned long specificity() const override;
166170
SimpleSelector* unifyWith(const SimpleSelector*);
167171
CompoundSelector* unifyWith(CompoundSelector*) override;
@@ -178,6 +182,7 @@ namespace Sass {
178182
class ClassSelector final : public SimpleSelector {
179183
public:
180184
ClassSelector(SourceSpan pstate, sass::string n);
185+
int getSortOrder() const override final { return 3; }
181186
virtual unsigned long specificity() const override;
182187
bool operator==(const SimpleSelector& rhs) const final override;
183188
ATTACH_CMP_OPERATIONS(ClassSelector)
@@ -191,6 +196,7 @@ namespace Sass {
191196
class IDSelector final : public SimpleSelector {
192197
public:
193198
IDSelector(SourceSpan pstate, sass::string n);
199+
int getSortOrder() const override final { return 2; }
194200
virtual unsigned long specificity() const override;
195201
CompoundSelector* unifyWith(CompoundSelector*) override;
196202
IDSelector* getIdSelector() final override { return this; }
@@ -210,6 +216,7 @@ namespace Sass {
210216
ADD_PROPERTY(char, modifier);
211217
public:
212218
AttributeSelector(SourceSpan pstate, sass::string n, sass::string m, String_Obj v, char o = 0);
219+
int getSortOrder() const override final { return 4; }
213220
size_t hash() const override;
214221
virtual unsigned long specificity() const override;
215222
bool operator==(const SimpleSelector& rhs) const final override;
@@ -230,6 +237,7 @@ namespace Sass {
230237
ADD_PROPERTY(bool, isClass)
231238
public:
232239
PseudoSelector(SourceSpan pstate, sass::string n, bool element = false);
240+
int getSortOrder() const override final { return 5; }
233241
virtual bool is_pseudo_element() const override;
234242
size_t hash() const override;
235243

@@ -445,6 +453,8 @@ namespace Sass {
445453
bool operator==(const ComplexSelector& rhs) const;
446454
bool operator==(const SimpleSelector& rhs) const;
447455

456+
void sortChildren();
457+
448458
ATTACH_CMP_OPERATIONS(CompoundSelector)
449459
ATTACH_AST_OPERATIONS(CompoundSelector)
450460
ATTACH_CRTP_PERFORM_METHODS()

src/inspect.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,6 +1091,7 @@ namespace Sass {
10911091
if (sel->hasRealParent()) {
10921092
append_string("&");
10931093
}
1094+
sel->sortChildren();
10941095
for (auto& item : sel->elements()) {
10951096
item->perform(this);
10961097
}

0 commit comments

Comments
 (0)