Skip to content

Commit 3157321

Browse files
committed
Add hotfix to avoid invalid nested :not selectors
1 parent 4bf831e commit 3157321

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:
@@ -2640,6 +2643,7 @@ namespace Sass {
26402643
virtual bool has_parent_ref() const;
26412644
virtual bool has_real_parent_ref() const;
26422645
virtual unsigned long specificity() const;
2646+
virtual bool find ( bool (*f)(AST_Node_Obj) );
26432647
virtual bool operator==(const Simple_Selector& rhs) const;
26442648
virtual bool operator==(const Wrapped_Selector& rhs) const;
26452649
virtual bool operator<(const Simple_Selector& rhs) const;
@@ -2737,6 +2741,7 @@ namespace Sass {
27372741
Cast<Parent_Selector>((*this)[0]);
27382742
}
27392743

2744+
virtual bool find ( bool (*f)(AST_Node_Obj) );
27402745
virtual bool operator<(const Selector& rhs) const;
27412746
virtual bool operator==(const Selector& rhs) const;
27422747
virtual bool operator<(const Compound_Selector& rhs) const;
@@ -2858,6 +2863,7 @@ namespace Sass {
28582863
if (tail_ && tail_->has_placeholder()) return true;
28592864
return false;
28602865
}
2866+
virtual bool find ( bool (*f)(AST_Node_Obj) );
28612867
virtual bool operator<(const Selector& rhs) const;
28622868
virtual bool operator==(const Selector& rhs) const;
28632869
virtual bool operator<(const Complex_Selector& rhs) const;
@@ -2982,6 +2988,7 @@ namespace Sass {
29822988
}
29832989
return false;
29842990
}
2991+
virtual bool find ( bool (*f)(AST_Node_Obj) );
29852992
virtual bool operator<(const Selector& rhs) const;
29862993
virtual bool operator==(const Selector& rhs) const;
29872994
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
@@ -937,18 +937,31 @@ namespace Sass {
937937
}
938938
}
939939

940+
// hotfix to avoid invalid nested `:not` selectors
941+
// probably the wrong place, but this should ultimatively
942+
// be fixed by implement superselector correctly for `:not`
943+
// first use of "find" (ATM only implemented for selectors)
944+
bool hasNotSelector(AST_Node_Obj obj) {
945+
if (Wrapped_Selector_Ptr w = Cast<Wrapped_Selector>(obj)) {
946+
return w->name() == ":not";
947+
}
948+
return false;
949+
}
950+
940951
void Inspect::operator()(Wrapped_Selector_Ptr s)
941952
{
942-
bool was = in_wrapped;
943-
in_wrapped = true;
944-
append_token(s->name(), s);
945-
append_string("(");
946-
bool was_comma_array = in_comma_array;
947-
in_comma_array = false;
948-
s->selector()->perform(this);
949-
in_comma_array = was_comma_array;
950-
append_string(")");
951-
in_wrapped = was;
953+
if (!s->selector()->find(hasNotSelector)) {
954+
bool was = in_wrapped;
955+
in_wrapped = true;
956+
append_token(s->name(), s);
957+
append_string("(");
958+
bool was_comma_array = in_comma_array;
959+
in_comma_array = false;
960+
s->selector()->perform(this);
961+
in_comma_array = was_comma_array;
962+
append_string(")");
963+
in_wrapped = was;
964+
}
952965
}
953966

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

0 commit comments

Comments
 (0)