Skip to content

Commit

Permalink
Fix various pending issues [WIP]
Browse files Browse the repository at this point in the history
  • Loading branch information
mgreter committed May 12, 2015
1 parent 71a5189 commit 021bdfb
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 31 deletions.
87 changes: 68 additions & 19 deletions ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,23 @@ namespace Sass {
if (!lbase) // no lbase; just see if the left-hand qualifiers are a subset of the right-hand selector
{
for (size_t i = 0, L = length(); i < L; ++i)
{ lset.insert((*this)[i]->perform(&to_string)); }
{
Selector* lhs = (*this)[i];
if (Wrapped_Selector* wrapped = dynamic_cast<Wrapped_Selector*>(lhs)) {
if (
wrapped->name() == ":matches(" ||
wrapped->name() == ":-moz-any("
) {
lhs = wrapped->selector();
if (Selector_List* list = dynamic_cast<Selector_List*>(lhs)) {
if (Compound_Selector* comp = dynamic_cast<Compound_Selector*>(rhs)) {
if (list->is_superselector_of(comp)) return true;
}
}
}
}
lset.insert(lhs->perform(&to_string));
}
for (size_t i = 0, L = rhs->length(); i < L; ++i)
{ rset.insert((*rhs)[i]->perform(&to_string)); }
return includes(rset.begin(), rset.end(), lset.begin(), lset.end());
Expand Down Expand Up @@ -326,8 +342,8 @@ namespace Sass {

bool Complex_Selector::is_superselector_of(Compound_Selector* rhs)
{
if (length() != 1)
{ return false; }
// if (base()->length() != 1)
// { return false; }
return base()->is_superselector_of(rhs);
}

Expand All @@ -352,6 +368,16 @@ namespace Sass {
if (l_len == 1)
{ return lhs->head()->is_superselector_of(rhs->base()); }

// we have to look one tail deeper, since we cary the
// combinator around for it (which is important here)
if (rhs->tail() && lhs->tail() && combinator() != Complex_Selector::ANCESTOR_OF) {
Complex_Selector* lhs_tail = lhs->tail();
Complex_Selector* rhs_tail = rhs->tail();
if (lhs_tail->combinator() != rhs_tail->combinator()) return false;
if (!lhs_tail->head()->is_superselector_of(rhs_tail->head())) return false;
}


bool found = false;
Complex_Selector* marker = rhs;
for (size_t i = 0, L = rhs->length(); i < L; ++i) {
Expand Down Expand Up @@ -493,22 +519,45 @@ namespace Sass {
#endif
}

bool Selector_List::is_superselector_of(Sass::Selector_List *rhs) {
// For every selector in RHS, see if it matches /any/ of our selectors
for(size_t rhs_i = 0, rhs_L = rhs->length(); rhs_i < rhs_L; ++rhs_i) {
Complex_Selector* seq1 = (*rhs)[rhs_i];
bool any = false;
for (size_t lhs_i = 0, lhs_L = length(); lhs_i < lhs_L; ++lhs_i) {
Complex_Selector* seq2 = (*this)[lhs_i];
bool is_superselector = seq2->is_superselector_of(seq1);
if( is_superselector ) {
any = true;
break;
}
}
if(!any) {
return false;
}
// it's a superselector if every selector on the right side
// is a superselector of any one of the left side selectors
bool Complex_Selector::is_superselector_of(Selector_List *sub)
{
// Check every rhs selector against left hand list
for(size_t i = 0, L = sub->length(); i < L; ++i) {
if (!is_superselector_of((*sub)[i])) return false;
}
return true;
}

// it's a superselector if every selector on the right side
// is a superselector of any one of the left side selectors
bool Selector_List::is_superselector_of(Compound_Selector *sub)
{
// cerr << "is_superselector_of Selector_List Selector_List\n";
// Check every rhs selector against left hand list
for(size_t i = 0, L = length(); i < L; ++i) {
if ((*this)[i]->is_superselector_of(sub)) return true;
}
return false;
}

bool Selector_List::is_superselector_of(Complex_Selector *sub)
{
// cerr << "is_superselector_of Selector_List Complex_Selector\n";
for(size_t i = 0, L = length(); i < L; ++i) {
if ((*this)[i]->is_superselector_of(sub)) return true;
}
return false;
}

// it's a superselector if every selector on the right side
// is a superselector of any one of the left side selectors
bool Selector_List::is_superselector_of(Selector_List *sub)
{
// Check every rhs selector against left hand list
for(size_t i = 0, L = sub->length(); i < L; ++i) {
if (!is_superselector_of((*sub)[i])) return false;
}
return true;
}
Expand Down
13 changes: 9 additions & 4 deletions ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1943,7 +1943,9 @@ namespace Sass {
return (*this)[0];
return 0;
}
bool is_superselector_of(Compound_Selector* rhs);
bool is_superselector_of(Compound_Selector* sub);
bool is_superselector_of(Complex_Selector* sub);
bool is_superselector_of(Selector_List* sub);
virtual unsigned long specificity()
{
int sum = 0;
Expand Down Expand Up @@ -2000,8 +2002,9 @@ namespace Sass {
Complex_Selector* context(Context&);
Complex_Selector* innermost();
size_t length();
bool is_superselector_of(Compound_Selector*);
bool is_superselector_of(Complex_Selector*);
bool is_superselector_of(Compound_Selector* sub);
bool is_superselector_of(Complex_Selector* sub);
bool is_superselector_of(Selector_List* sub);
// virtual Selector_Placeholder* find_placeholder();
Combinator clear_innermost();
void set_innermost(Complex_Selector*, Combinator);
Expand Down Expand Up @@ -2086,7 +2089,9 @@ namespace Sass {
: Selector(pstate), Vectorized<Complex_Selector*>(s), wspace_(0)
{ }
// virtual Selector_Placeholder* find_placeholder();
bool is_superselector_of(Selector_List* other);
bool is_superselector_of(Compound_Selector* sub);
bool is_superselector_of(Complex_Selector* sub);
bool is_superselector_of(Selector_List* sub);
virtual unsigned long specificity()
{
unsigned long sum = 0;
Expand Down
10 changes: 5 additions & 5 deletions functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1568,12 +1568,12 @@ namespace Sass {
BUILT_IN(is_superselector)
{
To_String to_string(&ctx, false);
Expression* ex_sub = ARG("$sub", Expression);
Expression* ex_sup = ARG("$super", Expression);
string sub_src = ex_sub->perform(&to_string) + "{";
Expression* ex_sup = ARG("$super", Expression);
Expression* ex_sub = ARG("$sub", Expression);
string sup_src = ex_sup->perform(&to_string) + "{";
Complex_Selector* sel_sub = Parser::parse_complex_selector(sub_src.c_str(), ctx);
Complex_Selector* sel_sup = Parser::parse_complex_selector(sup_src.c_str(), ctx);
string sub_src = ex_sub->perform(&to_string) + "{";
Selector_List* sel_sup = Parser::parse_selector(sup_src.c_str(), ctx);
Selector_List* sel_sub = Parser::parse_selector(sub_src.c_str(), ctx);
bool result = sel_sup->is_superselector_of(sel_sub);
return new (ctx.mem) Boolean(pstate, result);
}
Expand Down
5 changes: 3 additions & 2 deletions parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,15 @@ namespace Sass {
return p;
}

Complex_Selector* Parser::parse_complex_selector(const char* src, Context& ctx)
Selector_List* Parser::parse_selector(const char* src, Context& ctx)
{
Parser p = Parser::from_c_str(src, ctx, ParserState("sel", src, 0));
// if(contextualize.parent) {
// p.block_stack.push_back(contextualize.parent->last_block());
// p.last_media_block = contextualize.parent->media_block();
// }
return p.parse_selector_combination();
// ruby sass seems to disallow parent refs
return p.parse_selector_group();
}

bool Parser::peek_newline(const char* start)
Expand Down
2 changes: 1 addition & 1 deletion parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ namespace Sass {
static Parser from_c_str(const char* beg, const char* end, Context& ctx, ParserState pstate = ParserState("[CSTRING]"));
static Parser from_token(Token t, Context& ctx, ParserState pstate = ParserState("[TOKEN]"));
// special static parsers to convert strings into certain selectors
static Complex_Selector* parse_complex_selector(const char* src, Context& ctx);
static Selector_List* parse_selector(const char* src, Context& ctx);

#ifdef __clang__

Expand Down

0 comments on commit 021bdfb

Please sign in to comment.