Skip to content

Commit 2d640a7

Browse files
committed
Add hotfix to avoid invalid nested :not selectors
1 parent debb1e3 commit 2d640a7

File tree

3 files changed

+69
-10
lines changed

3 files changed

+69
-10
lines changed

src/ast.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,45 @@ namespace Sass {
1919

2020
static Null sass_null(ParserState("null"));
2121

22+
bool Wrapped_Selector::find ( bool (*f)(AST_Node_Obj) )
23+
{
24+
// check children first
25+
if (selector_) {
26+
if (selector_->find(f)) return true;
27+
}
28+
// execute last
29+
return f(this);
30+
}
31+
32+
bool Selector_List::find ( bool (*f)(AST_Node_Obj) )
33+
{
34+
// check children first
35+
for (Complex_Selector_Obj sel : elements()) {
36+
if (sel->find(f)) return true;
37+
}
38+
// execute last
39+
return f(this);
40+
}
41+
42+
bool Compound_Selector::find ( bool (*f)(AST_Node_Obj) )
43+
{
44+
// check children first
45+
for (Simple_Selector_Obj sel : elements()) {
46+
if (sel->find(f)) return true;
47+
}
48+
// execute last
49+
return f(this);
50+
}
51+
52+
bool Complex_Selector::find ( bool (*f)(AST_Node_Obj) )
53+
{
54+
// check children first
55+
if (head_ && head_->find(f)) return true;
56+
if (tail_ && tail_->find(f)) return true;
57+
// execute last
58+
return f(this);
59+
}
60+
2261
bool Supports_Operator::needs_parens(Supports_Condition_Obj cond) const {
2362
if (Supports_Operator_Obj op = Cast<Supports_Operator>(cond)) {
2463
return op->operand() != operand();

src/ast.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ namespace Sass {
124124
virtual const std::string to_string(Sass_Inspect_Options opt) const;
125125
virtual const std::string to_string() const;
126126
virtual void cloneChildren() {};
127+
// generic find function (not fully implemented yet)
128+
// ToDo: add specific implementions to all children
129+
virtual bool find ( bool (*f)(AST_Node_Obj) ) { return f(this); };
127130
public:
128131
void update_pstate(const ParserState& pstate);
129132
public:
@@ -2644,6 +2647,7 @@ namespace Sass {
26442647
virtual bool has_parent_ref() const;
26452648
virtual bool has_real_parent_ref() const;
26462649
virtual unsigned long specificity() const;
2650+
virtual bool find ( bool (*f)(AST_Node_Obj) );
26472651
virtual bool operator==(const Simple_Selector& rhs) const;
26482652
virtual bool operator==(const Wrapped_Selector& rhs) const;
26492653
virtual bool operator<(const Simple_Selector& rhs) const;
@@ -2741,6 +2745,7 @@ namespace Sass {
27412745
Cast<Parent_Selector>((*this)[0]);
27422746
}
27432747

2748+
virtual bool find ( bool (*f)(AST_Node_Obj) );
27442749
virtual bool operator<(const Selector& rhs) const;
27452750
virtual bool operator==(const Selector& rhs) const;
27462751
virtual bool operator<(const Compound_Selector& rhs) const;
@@ -2862,6 +2867,7 @@ namespace Sass {
28622867
if (tail_ && tail_->has_placeholder()) return true;
28632868
return false;
28642869
}
2870+
virtual bool find ( bool (*f)(AST_Node_Obj) );
28652871
virtual bool operator<(const Selector& rhs) const;
28662872
virtual bool operator==(const Selector& rhs) const;
28672873
virtual bool operator<(const Complex_Selector& rhs) const;
@@ -2986,6 +2992,7 @@ namespace Sass {
29862992
}
29872993
return false;
29882994
}
2995+
virtual bool find ( bool (*f)(AST_Node_Obj) );
29892996
virtual bool operator<(const Selector& rhs) const;
29902997
virtual bool operator==(const Selector& rhs) const;
29912998
virtual bool operator<(const Selector_List& rhs) const;

src/inspect.cpp

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -959,18 +959,31 @@ namespace Sass {
959959
}
960960
}
961961

962+
// hotfix to avoid invalid nested `:not` selectors
963+
// probably the wrong place, but this should ultimatively
964+
// be fixed by implement superselector correctly for `:not`
965+
// first use of "find" (ATM only implemented for selectors)
966+
bool hasNotSelector(AST_Node_Obj obj) {
967+
if (Wrapped_Selector_Ptr w = Cast<Wrapped_Selector>(obj)) {
968+
return w->name() == ":not";
969+
}
970+
return false;
971+
}
972+
962973
void Inspect::operator()(Wrapped_Selector_Ptr s)
963974
{
964-
bool was = in_wrapped;
965-
in_wrapped = true;
966-
append_token(s->name(), s);
967-
append_string("(");
968-
bool was_comma_array = in_comma_array;
969-
in_comma_array = false;
970-
s->selector()->perform(this);
971-
in_comma_array = was_comma_array;
972-
append_string(")");
973-
in_wrapped = was;
975+
if (!s->selector()->find(hasNotSelector)) {
976+
bool was = in_wrapped;
977+
in_wrapped = true;
978+
append_token(s->name(), s);
979+
append_string("(");
980+
bool was_comma_array = in_comma_array;
981+
in_comma_array = false;
982+
s->selector()->perform(this);
983+
in_comma_array = was_comma_array;
984+
append_string(")");
985+
in_wrapped = was;
986+
}
974987
}
975988

976989
void Inspect::operator()(Compound_Selector_Ptr s)

0 commit comments

Comments
 (0)