Skip to content

Commit

Permalink
Merge pull request #618 from xzyfer/feat/hoist-feature-queries
Browse files Browse the repository at this point in the history
Hoist selectors in feature queries
  • Loading branch information
xzyfer committed Nov 4, 2014
2 parents 068add9 + 40693d5 commit 5f3558d
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 8 deletions.
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

0 comments on commit 5f3558d

Please sign in to comment.