void Output::operator()(Keyframe_Rule* r) { Block* b = r->block(); Selector* v = r->selector(); if (v) { v->perform(this); } if (!b) { append_colon_separator(); return; } append_scope_opener(); for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (!stm->is_hoistable()) { stm->perform(this); if (i < L - 1) append_special_linefeed(); } } for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (stm->is_hoistable()) { stm->perform(this); } } append_scope_closer(); }
void Output_Compressed::operator()(At_Rule* a) { string kwd = a->keyword(); Selector* s = a->selector(); Block* b = a->block(); append_singleline_part_to_buffer(kwd); if (s) { append_singleline_part_to_buffer(" "); s->perform(this); } if (!b) { append_singleline_part_to_buffer(";"); return; } append_singleline_part_to_buffer("{"); for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (!stm->is_hoistable()) { stm->perform(this); } } for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (stm->is_hoistable()) { stm->perform(this); } } append_singleline_part_to_buffer("}"); }
void Output_Compressed::operator()(Ruleset* r) { Selector* s = r->selector(); Block* b = r->block(); if (s->has_placeholder()) return; if (b->has_non_hoistable()) { s->perform(this); append_singleline_part_to_buffer("{"); for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (!stm->is_hoistable()) { stm->perform(this); } } append_singleline_part_to_buffer("}"); } if (b->has_hoistable()) { for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (stm->is_hoistable()) { stm->perform(this); } } } }
void Output_Nested::operator()(Media_Block* m) { List* q = m->media_queries(); Block* b = m->block(); bool decls = false; indent(); ctx->source_map.add_mapping(m); append_singleline_part_to_buffer("@media "); q->perform(this); append_multiline_part_to_buffer(" {\n"); Selector* e = m->enclosing_selector(); bool hoisted = false; if (e && b->has_non_hoistable()) { hoisted = true; ++indentation; indent(); e->perform(this); append_multiline_part_to_buffer(" {\n"); } ++indentation; decls = true; for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (!stm->is_hoistable()) { if (!stm->block()) indent(); stm->perform(this); append_multiline_part_to_buffer("\n"); } } --indentation; if (hoisted) { buffer.erase(buffer.length()-1); if (ctx) ctx->source_map.remove_line(); append_multiline_part_to_buffer(" }\n"); --indentation; } if (decls) ++indentation; if (hoisted) ++indentation; for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (stm->is_hoistable()) { stm->perform(this); } } if (hoisted) --indentation; if (decls) --indentation; buffer.erase(buffer.length()-1); if (ctx) ctx->source_map.remove_line(); append_multiline_part_to_buffer(" }\n"); }
void Output_Nested::operator()(At_Rule* a) { string kwd = a->keyword(); Selector* s = a->selector(); Expression* v = a->value(); Block* b = a->block(); bool decls = false; // indent(); append_to_buffer(kwd); if (s) { append_to_buffer(" "); s->perform(this); } else if (v) { append_to_buffer(" "); v->perform(this); } if (!b) { append_to_buffer(";"); return; } append_to_buffer(" {\n"); ++indentation; decls = true; for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (!stm->is_hoistable()) { if (!stm->block()) indent(); stm->perform(this); append_to_buffer("\n"); } } --indentation; if (decls) ++indentation; for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (stm->is_hoistable()) { stm->perform(this); append_to_buffer("\n"); } } if (decls) --indentation; buffer.erase(buffer.length()-1); if (ctx) ctx->source_map.remove_line(); if (b->has_hoistable()) { buffer.erase(buffer.length()-1); if (ctx) ctx->source_map.remove_line(); } append_to_buffer(" }\n"); }
void Output_Nested::operator()(Media_Block* m) { List* q = m->media_queries(); Block* b = m->block(); bool decls = false; indent(); buffer += "@media "; q->perform(this); buffer += " {\n"; Selector* e = m->enclosing_selector(); bool hoisted = false; if (e && b->has_non_hoistable()) { hoisted = true; ++indentation; indent(); e->perform(this); buffer += " {\n"; } ++indentation; decls = true; for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (!stm->is_hoistable()) { if (!stm->block()) indent(); stm->perform(this); buffer += '\n'; } } --indentation; if (hoisted) { buffer.erase(buffer.length()-1); buffer += " }\n"; --indentation; } if (decls) ++indentation; if (hoisted) ++indentation; for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (stm->is_hoistable()) { stm->perform(this); } } if (hoisted) --indentation; if (decls) --indentation; buffer.erase(buffer.length()-1); buffer += " }\n"; }
void Output::operator()(Directive* a) { std::string kwd = a->keyword(); Selector* s = a->selector(); Expression* v = a->value(); Block* b = a->block(); append_indentation(); append_token(kwd, a); if (s) { append_mandatory_space(); in_wrapped = true; s->perform(this); in_wrapped = false; } if (v) { append_mandatory_space(); // ruby sass bug? should use options? append_token(v->to_string(/* opt */), v); } if (!b) { append_delimiter(); return; } if (b->is_invisible() || b->length() == 0) { append_optional_space(); return append_string("{}"); } append_scope_opener(); bool format = kwd != "@font-face";; for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (!stm->is_hoistable()) { stm->perform(this); if (i < L - 1 && format) append_special_linefeed(); } } for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (stm->is_hoistable()) { stm->perform(this); if (i < L - 1 && format) append_special_linefeed(); } } append_scope_closer(); }
Statement* Expand::operator()(At_Rule* a) { Block* ab = a->block(); selector_stack.push_back(0); Selector* as = a->selector(); if (as) as = as->perform(contextualize->with(0, env, backtrace)); Block* bb = ab ? ab->perform(this)->block() : 0; At_Rule* aa = new (ctx.mem) At_Rule(a->path(), a->position(), a->keyword(), as, bb); selector_stack.pop_back(); return aa; }
void Output_Nested::operator()(At_Rule* a) { string kwd = a->keyword(); Selector* s = a->selector(); Block* b = a->block(); bool decls = false; // indent(); buffer += kwd; if (s) { buffer += ' '; s->perform(this); } if (!b) { buffer += ';'; return; } buffer += " {\n"; ++indentation; decls = true; for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (!stm->is_hoistable()) { if (!stm->block()) indent(); stm->perform(this); buffer += '\n'; } } --indentation; if (decls) ++indentation; for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (stm->is_hoistable()) { stm->perform(this); buffer += '\n'; } } if (decls) --indentation; buffer.erase(buffer.length()-1); if (b->has_hoistable()) { buffer.erase(buffer.length()-1); } buffer += " }\n"; }
void Output_Nested::operator()(Ruleset* r) { Selector* s = r->selector(); Block* b = r->block(); bool decls = false; if (s->has_placeholder()) return; if (b->has_non_hoistable()) { decls = true; indent(); if (source_comments) { stringstream ss; ss << "/* line " << r->line() << ", " << r->path() << " */" << endl; buffer += ss.str(); indent(); } s->perform(this); buffer += " {\n"; ++indentation; for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (!stm->is_hoistable()) { if (!stm->block()) indent(); stm->perform(this); buffer += '\n'; } } --indentation; buffer.erase(buffer.length()-1); buffer += " }\n"; } if (b->has_hoistable()) { if (decls) ++indentation; // indent(); for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (stm->is_hoistable()) { stm->perform(this); } } if (decls) --indentation; } }
void Output_Compressed::operator()(Media_Block* m) { List* q = m->media_queries(); Block* b = m->block(); ctx->source_map.add_mapping(m); append_singleline_part_to_buffer("@media "); q->perform(this); append_singleline_part_to_buffer("{"); Selector* e = m->enclosing_selector(); bool hoisted = false; if (e && b->has_non_hoistable()) { hoisted = true; e->perform(this); append_singleline_part_to_buffer("{"); } for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (!stm->is_hoistable()) { stm->perform(this); } } if (hoisted) { append_singleline_part_to_buffer("}"); } for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (stm->is_hoistable()) { stm->perform(this); } } append_singleline_part_to_buffer("}"); }
void Output::operator()(Ruleset* r) { Selector* s = r->selector(); Block* b = r->block(); bool decls = false; // Filter out rulesets that aren't printable (process its children though) if (!Util::isPrintable(r, output_style())) { for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (dynamic_cast<Has_Block*>(stm)) { stm->perform(this); } } return; } if (b->has_non_hoistable()) { decls = true; if (output_style() == NESTED) indentation += r->tabs(); if (opt.source_comments) { std::stringstream ss; append_indentation(); ss << "/* line " << r->pstate().line + 1 << ", " << r->pstate().path << " */"; append_string(ss.str()); append_optional_linefeed(); } s->perform(this); append_scope_opener(b); for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; bool bPrintExpression = true; // Check print conditions if (typeid(*stm) == typeid(Declaration)) { Declaration* dec = static_cast<Declaration*>(stm); if (dec->value()->concrete_type() == Expression::STRING) { String_Constant* valConst = static_cast<String_Constant*>(dec->value()); std::string val(valConst->value()); if (auto qstr = dynamic_cast<String_Quoted*>(valConst)) { if (!qstr->quote_mark() && val.empty()) { bPrintExpression = false; } } } else if (dec->value()->concrete_type() == Expression::LIST) { List* list = static_cast<List*>(dec->value()); bool all_invisible = true; for (size_t list_i = 0, list_L = list->length(); list_i < list_L; ++list_i) { Expression* item = (*list)[list_i]; if (!item->is_invisible()) all_invisible = false; } if (all_invisible) bPrintExpression = false; } } // Print if OK if (!stm->is_hoistable() && bPrintExpression) { stm->perform(this); } } if (output_style() == NESTED) indentation -= r->tabs(); append_scope_closer(b); } if (b->has_hoistable()) { if (decls) ++indentation; for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (stm->is_hoistable()) { stm->perform(this); } } if (decls) --indentation; } }
void Output_Nested::operator()(Ruleset* r) { Selector* s = r->selector(); Block* b = r->block(); bool decls = false; if (s->has_placeholder()) return; if (b->has_non_hoistable()) { decls = true; indent(); if (source_comments) { stringstream ss; ss << "/* line " << r->line() << ", " << r->path() << " */" << endl; buffer += ss.str(); indent(); } s->perform(this); buffer += " {\n"; ++indentation; for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; bool bPrintExpression = true; // Check print conditions if (typeid(*stm) == typeid(Declaration)) { Declaration* dec = static_cast<Declaration*>(stm); if (dec->value()->concrete_type() == Expression::STRING) { String_Constant* valConst = static_cast<String_Constant*>(dec->value()); string val(valConst->value()); if (val.empty()) { bPrintExpression = false; } } else if (dec->value()->concrete_type() == Expression::LIST) { List* list = static_cast<List*>(dec->value()); bool all_invisible = true; for (size_t list_i = 0, list_L = list->length(); list_i < list_L; ++list_i) { Expression* item = (*list)[list_i]; if (!item->is_invisible()) all_invisible = false; } if (all_invisible) bPrintExpression = false; } } // Print if OK if (!stm->is_hoistable() && bPrintExpression) { if (!stm->block()) indent(); stm->perform(this); buffer += '\n'; } } --indentation; buffer.erase(buffer.length()-1); buffer += " }\n"; } if (b->has_hoistable()) { if (decls) ++indentation; // indent(); for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (stm->is_hoistable()) { stm->perform(this); } } if (decls) --indentation; } }
void Output_Nested::operator()(Ruleset* r) { Selector* s = r->selector(); Block* b = r->block(); bool decls = false; // In case the extend visitor isn't called (if there are no @extend // directives in the entire document), check for placeholders here and // make sure they aren't output. // TODO: investigate why I decided to duplicate this logic in the extend visitor Selector_List* sl = static_cast<Selector_List*>(s); if (!ctx->extensions.size()) { Selector_List* new_sl = new (ctx->mem) Selector_List(sl->path(), sl->position()); for (size_t i = 0, L = sl->length(); i < L; ++i) { if (!(*sl)[i]->has_placeholder()) { *new_sl << (*sl)[i]; } } s = new_sl; sl = new_sl; r->selector(new_sl); } if (sl->length() == 0) return; if (b->has_non_hoistable()) { decls = true; indent(); if (source_comments) { stringstream ss; ss << "/* line " << r->position().line << ", " << r->path() << " */" << endl; append_singleline_part_to_buffer(ss.str()); indent(); } s->perform(this); append_multiline_part_to_buffer(" {\n"); ++indentation; for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; bool bPrintExpression = true; // Check print conditions if (typeid(*stm) == typeid(Declaration)) { Declaration* dec = static_cast<Declaration*>(stm); if (dec->value()->concrete_type() == Expression::STRING) { String_Constant* valConst = static_cast<String_Constant*>(dec->value()); string val(valConst->value()); if (val.empty()) { bPrintExpression = false; } } else if (dec->value()->concrete_type() == Expression::LIST) { List* list = static_cast<List*>(dec->value()); bool all_invisible = true; for (size_t list_i = 0, list_L = list->length(); list_i < list_L; ++list_i) { Expression* item = (*list)[list_i]; if (!item->is_invisible()) all_invisible = false; } if (all_invisible) bPrintExpression = false; } } // Print if OK if (!stm->is_hoistable() && bPrintExpression) { if (!stm->block()) indent(); stm->perform(this); append_multiline_part_to_buffer("\n"); } } --indentation; buffer.erase(buffer.length()-1); if (ctx) ctx->source_map.remove_line(); append_multiline_part_to_buffer(" }\n"); } if (b->has_hoistable()) { if (decls) ++indentation; // indent(); for (size_t i = 0, L = b->length(); i < L; ++i) { Statement* stm = (*b)[i]; if (stm->is_hoistable()) { stm->perform(this); } } if (decls) --indentation; } }