Skip to content

Commit

Permalink
Support parent selector & in values / and/or interpolations sass#548
Browse files Browse the repository at this point in the history
  • Loading branch information
Eric Kimn committed Feb 5, 2015
1 parent a915970 commit 158a5af
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 4 deletions.
7 changes: 4 additions & 3 deletions ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ namespace Sass {
STRING,
LIST,
MAP,
SELECTOR,
NULL_VAL,
NUM_TYPES
};
Expand Down Expand Up @@ -1685,13 +1686,13 @@ namespace Sass {
/////////////////////////////////////////
// Abstract base class for CSS selectors.
/////////////////////////////////////////
class Selector : public AST_Node {
class Selector : public Expression {
ADD_PROPERTY(bool, has_reference);
ADD_PROPERTY(bool, has_placeholder);
public:
Selector(ParserState pstate, bool r = false, bool h = false)
: AST_Node(pstate), has_reference_(r), has_placeholder_(h)
{ }
: Expression(pstate), has_reference_(r), has_placeholder_(h)
{ concrete_type(SELECTOR); }
virtual ~Selector() = 0;
virtual Selector_Placeholder* find_placeholder();
virtual int specificity() { return Constants::SPECIFICITY_BASE; }
Expand Down
5 changes: 5 additions & 0 deletions eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,11 @@ namespace Sass {
e->is_interpolated());
}

Expression* Eval::operator()(Selector_Reference* e)
{
return e;
}

Expression* Eval::operator()(Null* n)
{
return n;
Expand Down
1 change: 1 addition & 0 deletions eval.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ namespace Sass {
Expression* operator()(String_Constant*);
Expression* operator()(Media_Query*);
Expression* operator()(Media_Query_Expression*);
Expression* operator()(Selector_Reference*);
Expression* operator()(At_Root_Expression*);
Expression* operator()(Feature_Query*);
Expression* operator()(Feature_Query_Condition*);
Expand Down
49 changes: 48 additions & 1 deletion expand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,54 @@ namespace Sass {
if (!a->is_guarded() || v->concrete_type() == Expression::NULL_VAL) (*env)[var] = a->value()->perform(eval->with(env, backtrace));
}
else {
env->current_frame()[var] = a->value()->perform(eval->with(env, backtrace));
Selector_Reference* v = static_cast<Selector_Reference*> (a->value ());
if (v->concrete_type () == Expression::SELECTOR) {
bool old_in_at_root = in_at_root;
in_at_root = false;
Contextualize* contextual = contextualize->with (
selector_stack.back (), env, backtrace);
if (old_in_at_root && !v->has_reference ())
contextual = contextualize->with (at_root_selector_stack.back (),
env, backtrace);

Selector* sel_ctx = v->perform (contextual);

Inspect isp (0);
sel_ctx->perform (&isp);
string str = isp.get_buffer ();
str += ";";

Parser p (ctx, ParserState ("[REPARSE]", 0));
p.source = str.c_str ();
p.position = str.c_str ();
p.end = str.c_str () + strlen (str.c_str ());
Selector_List* sel_lst = p.parse_selector_group ();
sel_lst->pstate (isp.source_map.remap (sel_lst->pstate ()));

for (size_t i = 0; i < sel_lst->length (); i++) {
Complex_Selector* pIter = (*sel_lst)[i];
while (pIter) {
Compound_Selector* pHead = pIter->head ();
pIter->pstate (isp.source_map.remap (pIter->pstate ()));
if (pHead) {
pHead->pstate (isp.source_map.remap (pHead->pstate ()));
(*pHead)[0]->pstate (
isp.source_map.remap ((*pHead)[0]->pstate ()));
}
pIter = pIter->tail ();
}
}
sel_ctx = sel_lst;

selector_stack.push_back (sel_ctx);
selector_stack.pop_back ();
in_at_root = old_in_at_root;
old_in_at_root = false;
env->current_frame ()[var] = sel_ctx;
}
else {
env->current_frame()[var] = a->value()->perform(eval->with(env, backtrace));
}
}
return 0;
}
Expand Down
4 changes: 4 additions & 0 deletions parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1219,6 +1219,10 @@ namespace Sass {
if (lex< sequence< exactly<'%'>, optional< percentage > > >())
{ return new (ctx.mem) String_Constant(pstate, lexed); }

if (lex< ampersand >())
{
return new (ctx.mem) Selector_Reference(pstate);
}
error("error reading values after " + lexed.to_string(), pstate);

// unreachable statement
Expand Down
3 changes: 3 additions & 0 deletions prelexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,9 @@ namespace Sass {
const char* percentage(const char* src) {
return sequence< number, exactly<'%'> >(src);
}
const char* ampersand(const char* src) {
return exactly<'&'>(src);
}

const char* em(const char* src) {
return sequence< number, exactly<em_kwd> >(src);
Expand Down
1 change: 1 addition & 0 deletions prelexer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ namespace Sass {
const char* coefficient(const char* src);
const char* binomial(const char* src);
const char* percentage(const char* src);
const char* ampersand(const char* src);
const char* dimension(const char* src);
const char* hex(const char* src);
const char* hexa(const char* src);
Expand Down

0 comments on commit 158a5af

Please sign in to comment.