Skip to content
This repository was archived by the owner on Oct 24, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,9 +345,10 @@ namespace Sass {
///////////////////
class Feature_Block : public Has_Block {
ADD_PROPERTY(Feature_Queries*, feature_queries);
ADD_PROPERTY(Selector*, selector);
public:
Feature_Block(string path, Position position, Feature_Queries* fqs, Block* b)
: Has_Block(path, position, b), feature_queries_(fqs)
: Has_Block(path, position, b), feature_queries_(fqs), selector_(0)
{ }
bool is_hoistable() { return true; }
ATTACH_OPERATIONS();
Expand Down
1 change: 1 addition & 0 deletions expand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ namespace Sass {
f->position(),
static_cast<Feature_Queries*>(feature_queries),
f->block()->perform(this)->block());
ff->selector(selector_stack.back());
return ff;
}

Expand Down
4 changes: 4 additions & 0 deletions extend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1939,6 +1939,10 @@ namespace Sass {

void Extend::operator()(Feature_Block* pFeatureBlock)
{
if (pFeatureBlock->selector()) {
extendObjectWithSelectorAndBlock(pFeatureBlock, ctx, subset_map);
}

pFeatureBlock->block()->perform(this);
}

Expand Down
86 changes: 81 additions & 5 deletions output_nested.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,82 @@ namespace Sass {
}
}

void Output_Nested::operator()(Feature_Block* f)
{
Feature_Queries* q = f->feature_queries();
Block* b = f->block();

// Filter out feature blocks that aren't printable (process its children though)
if (!Util::isPrintable(f)) {
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;
}

indent();
ctx->source_map.add_mapping(f);
append_to_buffer("@supports ");
q->perform(this);
append_to_buffer(" {\n");

Selector* e = f->selector();
if (e && b->has_non_hoistable()) {
// JMA - hoisted, output the non-hoistable in a nested block, followed by the hoistable
++indentation;
indent();
e->perform(this);
append_to_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);
append_to_buffer("\n");
}
}
--indentation;

buffer.erase(buffer.length()-1);
if (ctx) ctx->source_map.remove_line();
append_to_buffer(" }\n");
--indentation;

++indentation;
++indentation;
for (size_t i = 0, L = b->length(); i < L; ++i) {
Statement* stm = (*b)[i];
if (stm->is_hoistable()) {
stm->perform(this);
}
}
--indentation;
--indentation;
}
else {
// JMA - not hoisted, just output in order
++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);
append_to_buffer("\n");
}
--indentation;
}

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();
Expand All @@ -139,7 +215,7 @@ namespace Sass {
}
return;
}

indent();
ctx->source_map.add_mapping(m);
append_to_buffer("@media ");
Expand All @@ -153,7 +229,7 @@ namespace Sass {
indent();
e->perform(this);
append_to_buffer(" {\n");

++indentation;
for (size_t i = 0, L = b->length(); i < L; ++i) {
Statement* stm = (*b)[i];
Expand All @@ -164,12 +240,12 @@ namespace Sass {
}
}
--indentation;

buffer.erase(buffer.length()-1);
if (ctx) ctx->source_map.remove_line();
append_to_buffer(" }\n");
--indentation;

++indentation;
++indentation;
for (size_t i = 0, L = b->length(); i < L; ++i) {
Expand All @@ -194,7 +270,7 @@ namespace Sass {
}
--indentation;
}

buffer.erase(buffer.length()-1);
if (ctx) ctx->source_map.remove_line();
append_to_buffer(" }\n");
Expand Down
1 change: 1 addition & 0 deletions output_nested.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ namespace Sass {
virtual void operator()(Block*);
virtual void operator()(Ruleset*);
// virtual void operator()(Propset*);
virtual void operator()(Feature_Block*);
virtual void operator()(Media_Block*);
virtual void operator()(At_Rule*);
// virtual void operator()(Declaration*);
Expand Down
5 changes: 3 additions & 2 deletions util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@ namespace Sass {

Block* b = f->block();

bool hasSelectors = false;
bool hasSelectors = f->selector() && static_cast<Selector_List*>(f->selector())->length() > 0;

bool hasDeclarations = false;
bool hasPrintableChildBlocks = false;
for (size_t i = 0, L = b->length(); i < L; ++i) {
Statement* stm = (*b)[i];
if (!stm->is_hoistable() && !hasSelectors) {
if (!stm->is_hoistable() && f->selector() != NULL && !hasSelectors) {
// If a statement isn't hoistable, the selectors apply to it. If there are no selectors (a selector list of length 0),
// then those statements aren't considered printable. That means there was a placeholder that was removed. If the selector
// is NULL, then that means there was never a wrapping selector and it is printable (think of a top level media block with
Expand Down