From 53e5fb47096dcd0825f2fa5225f8bd0cc787f4c4 Mon Sep 17 00:00:00 2001 From: xzyfer Date: Sun, 11 Oct 2015 17:55:39 +1100 Subject: [PATCH] Fix regression is allowing `@extend`ing across media queries This PR fixes a regression is allowing `@extend`ing across media queries. Still needs a bit of work. Regressed in 9f5ef6da0e8ec9287cd800bf98174f049591b286 Fixes #1562 Spec https://github.com/sass/sass-spec/pull/538 --- src/eval.cpp | 1 + src/expand.cpp | 2 ++ src/parser.cpp | 15 ++++++++++++++- src/parser.hpp | 3 ++- 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/eval.cpp b/src/eval.cpp index b14d017ef5..13323912c6 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -1395,6 +1395,7 @@ namespace Sass { { std::vector rv; Selector_List* sl = SASS_MEMORY_NEW(ctx.mem, Selector_List, s->pstate()); + sl->media_block(s->media_block()); for (size_t i = 0, iL = s->length(); i < iL; ++i) { rv.push_back(operator()((*s)[i])); } diff --git a/src/expand.cpp b/src/expand.cpp index 1db33ec796..41d077c2be 100644 --- a/src/expand.cpp +++ b/src/expand.cpp @@ -553,6 +553,8 @@ namespace Sass { Complex_Selector* ssel = SASS_MEMORY_NEW(ctx.mem, Complex_Selector, (*extender)[i]->pstate()); if (sel->has_line_feed()) ssel->has_line_feed(true); *hh << SASS_MEMORY_NEW(ctx.mem, Parent_Selector, (*extender)[i]->pstate()); + hh->media_block((*extender)[i]->media_block()); + ssel->media_block((*extender)[i]->media_block()); ssel->tail(sel); ssel->head(hh); sel = ssel; diff --git a/src/parser.cpp b/src/parser.cpp index 08d163e2a7..6f742ad021 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -609,6 +609,7 @@ namespace Sass { String_Schema* schema = SASS_MEMORY_NEW(ctx.mem, String_Schema, pstate); // the selector schema is pretty much just a wrapper for the string schema Selector_Schema* selector_schema = SASS_MEMORY_NEW(ctx.mem, Selector_Schema, pstate, schema); + selector_schema->media_block(last_media_block); // process until end while (i < end_of_selector) { @@ -693,6 +694,7 @@ namespace Sass { Complex_Selector* sel = 0; To_String to_string(&ctx); Selector_List* group = SASS_MEMORY_NEW(ctx.mem, Selector_List, pstate); + group->media_block(last_media_block); do { reloop = false; @@ -774,6 +776,8 @@ namespace Sass { // source position of a complex selector points to the combinator // ToDo: make sure we update pstate for ancestor of (lex < zero >()); Complex_Selector* sel = SASS_MEMORY_NEW(ctx.mem, Complex_Selector, pstate, combinator, lhs); + sel->media_block(last_media_block); + if (combinator == Complex_Selector::REFERENCE) sel->reference(reference); // has linfeed after combinator? sel->has_line_break(peek_newline()); @@ -795,13 +799,18 @@ namespace Sass { if (!sel->has_reference() && !in_at_root && !in_root) { // create the objects to wrap parent selector reference Parent_Selector* parent = SASS_MEMORY_NEW(ctx.mem, Parent_Selector, pstate); + parent->media_block(last_media_block); Compound_Selector* head = SASS_MEMORY_NEW(ctx.mem, Compound_Selector, pstate); + head->media_block(last_media_block); // add simple selector (*head) << parent; // selector may not have any head yet if (!sel->head()) { sel->head(head); } // otherwise we need to create a new complex selector and set the old one as its tail - else { sel = SASS_MEMORY_NEW(ctx.mem, Complex_Selector, pstate, Complex_Selector::ANCESTOR_OF, head, sel); } + else { + sel = SASS_MEMORY_NEW(ctx.mem, Complex_Selector, pstate, Complex_Selector::ANCESTOR_OF, head, sel); + sel->media_block(last_media_block); + } // peek for linefeed and remember result on head // if (peek_newline()) head->has_line_break(true); } @@ -818,6 +827,7 @@ namespace Sass { { // init an empty compound selector wrapper Compound_Selector* seq = SASS_MEMORY_NEW(ctx.mem, Compound_Selector, pstate); + seq->media_block(last_media_block); // skip initial white-space lex< css_whitespace >(); @@ -1912,7 +1922,10 @@ namespace Sass { Media_Block* media_block = SASS_MEMORY_NEW(ctx.mem, Media_Block, pstate, 0, 0); media_block->media_queries(parse_media_queries()); + Media_Block* prev_media_block = last_media_block; + last_media_block = media_block; media_block->block(parse_css_block()); + last_media_block = prev_media_block; return media_block; } diff --git a/src/parser.hpp b/src/parser.hpp index 6639f4577d..92b665915f 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -32,6 +32,7 @@ namespace Sass { Context& ctx; std::vector block_stack; std::vector stack; + Media_Block* last_media_block; const char* source; const char* position; const char* end; @@ -45,7 +46,7 @@ namespace Sass { bool in_at_root; Parser(Context& ctx, const ParserState& pstate) - : ParserState(pstate), ctx(ctx), block_stack(0), stack(0), + : ParserState(pstate), ctx(ctx), block_stack(0), stack(0), last_media_block(0), source(0), position(0), end(0), before_token(pstate), after_token(pstate), pstate(pstate), indentation(0) { in_at_root = false; stack.push_back(nothing); }