Selector* Contextualize::operator()(Selector_Group* s) { Selector_Group* p = static_cast<Selector_Group*>(parent); Selector_Group* ss = 0; if (p) { ss = new (ctx.mem) Selector_Group(s->path(), s->line(), p->length() * s->length()); for (size_t i = 0, L = p->length(); i < L; ++i) { for (size_t j = 0, L = s->length(); j < L; ++j) { parent = (*p)[i]; Selector_Combination* comb = static_cast<Selector_Combination*>((*s)[j]->perform(this)); if (comb) *ss << comb; } } } else { ss = new (ctx.mem) Selector_Group(s->path(), s->line(), s->length()); for (size_t j = 0, L = s->length(); j < L; ++j) { Selector_Combination* comb = static_cast<Selector_Combination*>((*s)[j]->perform(this)); if (comb) *ss << comb; } } return ss->length() ? ss : 0; }
void Extend::operator()(Ruleset* r) { Selector_Group* sg = static_cast<Selector_Group*>(r->selector()); Selector_Group* ng = 0; bool extended = false; if (sg->has_placeholder()) { // To_String to_string; Simple_Selector_Sequence* placeholder = new (ctx.mem) Simple_Selector_Sequence(sg->path(), sg->line(), 1); *placeholder << sg->find_placeholder(); // cerr << "placeholder: " << placeholder->perform(&to_string) << endl; // if the placeholder needs to be subbed if (extensions.count(*placeholder)) { // cerr << "need to sub " << placeholder->perform(&to_string) << " " << extensions.count(*placeholder) << " times" << endl; // perform each substitution and append it to the selector group of the ruleset ng = new (ctx.mem) Selector_Group(sg->path(), sg->line(), extensions.count(*placeholder)); for (multimap<Simple_Selector_Sequence, Selector_Combination*>::iterator extender = extensions.lower_bound(*placeholder), E = extensions.upper_bound(*placeholder); extender != E; ++extender) { // cerr << "performing a substitution: " << placeholder->perform(&to_string) << " -> " << extender->second->perform(&to_string) << endl; Contextualize sub_plc(ctx, 0, 0, backtrace, placeholder, extender->second); Selector_Group* subbed = static_cast<Selector_Group*>(sg->perform(&sub_plc)); // if (subbed) cerr << "subbed: " << subbed->perform(&to_string) << endl; *ng += subbed; extended = true; } ng->has_placeholder(false); } // otherwise prevent it from rendering else { // r->selector(0); } } else { ng = new (ctx.mem) Selector_Group(sg->path(), sg->line(), sg->length()); // for each selector in the group for (size_t i = 0, L = sg->length(); i < L; ++i) { Selector_Combination* sel = (*sg)[i]; *ng << sel; // if it's supposed to be extended Simple_Selector_Sequence* sel_base = sel->base(); To_String to_string; if (sel_base && extensions.count(*sel_base)) { // extend it wrt each of its extenders for (multimap<Simple_Selector_Sequence, Selector_Combination*>::iterator extender = extensions.lower_bound(*sel_base), E = extensions.upper_bound(*sel_base); extender != E; ++extender) { *ng += generate_extension(sel, extender->second); extended = true; } } } } if (extended) r->selector(ng); r->block()->perform(this); }