diff --git a/src/extend.cpp b/src/extend.cpp index 604f6af12b..1c4e5a2c16 100644 --- a/src/extend.cpp +++ b/src/extend.cpp @@ -6,6 +6,7 @@ #include "parser.hpp" #include "node.hpp" #include "sass_util.hpp" +#include "remove_placeholders.hpp" #include "debug.hpp" #include #include @@ -1944,19 +1945,57 @@ namespace Sass { } } - for (Complex_Selector* cs : *pNewSelectors) { - while (cs) { - if (cs->head()) { - for (Simple_Selector* ss : *cs->head()) { - if (Wrapped_Selector* ws = dynamic_cast(ss)) { - if (Selector_List* sl = dynamic_cast(ws->selector())) { - bool extended = false; - ws->selector(extendSelectorList(sl, ctx, subset_map, false, extended)); + Remove_Placeholders remove_placeholders(ctx); + // it seems that we have to remove the place holders early here + // normally we do this as the very last step (compare to ruby sass) + pNewSelectors = remove_placeholders.remove_placeholders(pNewSelectors); + + // unwrap all wrapped selectors with inner lists + for (Complex_Selector* cur : *pNewSelectors) { + // process tails + while (cur) { + // process header + if (cur->head()) { + // create a copy since we add multiple items if stuff get unwrapped + Compound_Selector* cpy_head = SASS_MEMORY_NEW(ctx.mem, Compound_Selector, cur->pstate()); + for (Simple_Selector* hs : *cur->head()) { + if (Wrapped_Selector* ws = dynamic_cast(hs)) { + if (Selector_List* sl = dynamic_cast(ws->selector())) { + // special case for ruby ass + if (sl->empty()) { + // this seems inconsistent but it is how ruby sass seems to remove parentheses + *cpy_head << SASS_MEMORY_NEW(ctx.mem, Type_Selector, hs->pstate(), ws->name()); + } + // has wrapped selectors + else { + // extend the inner list of wrapped selector + Selector_List* ext_sl = extendSelectorList(sl, ctx, subset_map); + for (size_t i = 0; i < ext_sl->length(); i += 1) { + if (Complex_Selector* ext_cs = ext_sl->at(i)) { + // create clones for wrapped selector and the inner list + Wrapped_Selector* cpy_ws = SASS_MEMORY_NEW(ctx.mem, Wrapped_Selector, *ws); + Selector_List* cpy_ws_sl = SASS_MEMORY_NEW(ctx.mem, Selector_List, sl->pstate()); + // remove parent selectors from inner selector + if (ext_cs->first()) *cpy_ws_sl << ext_cs->first(); + // assign list to clone + cpy_ws->selector(cpy_ws_sl); + // append the clone + *cpy_head << cpy_ws; + } + } + } + } else { + *cpy_head << hs; + } + } else { + *cpy_head << hs; } } + // replace header + cur->head(cpy_head); } - } - cs = cs->tail(); + // process tail + cur = cur->tail(); } } return pNewSelectors; diff --git a/src/extend.hpp b/src/extend.hpp index 7061b3fada..ae86a926f6 100644 --- a/src/extend.hpp +++ b/src/extend.hpp @@ -24,6 +24,10 @@ namespace Sass { public: static Node subweave(Node& one, Node& two, Context& ctx); static Selector_List* extendSelectorList(Selector_List* pSelectorList, Context& ctx, ExtensionSubsetMap& subset_map, bool isReplace, bool& extendedSomething); + static Selector_List* extendSelectorList(Selector_List* pSelectorList, Context& ctx, ExtensionSubsetMap& subset_map, bool isReplace = false) { + bool extendedSomething = false; + return extendSelectorList(pSelectorList, ctx, subset_map, isReplace, extendedSomething); + } Extend(Context&, ExtensionSubsetMap&); ~Extend() { } diff --git a/src/functions.cpp b/src/functions.cpp index 8078255611..0de627b88c 100644 --- a/src/functions.cpp +++ b/src/functions.cpp @@ -1889,8 +1889,7 @@ namespace Sass { ExtensionSubsetMap subset_map; extender->populate_extends(extendee, ctx, subset_map); - bool extendedSomething; - Selector_List* result = Extend::extendSelectorList(selector, ctx, subset_map, false, extendedSomething); + Selector_List* result = Extend::extendSelectorList(selector, ctx, subset_map, false); Listize listize(ctx.mem); return result->perform(&listize); @@ -1906,8 +1905,7 @@ namespace Sass { ExtensionSubsetMap subset_map; replacement->populate_extends(original, ctx, subset_map); - bool extendedSomething; - Selector_List* result = Extend::extendSelectorList(selector, ctx, subset_map, true, extendedSomething); + Selector_List* result = Extend::extendSelectorList(selector, ctx, subset_map, true); Listize listize(ctx.mem); return result->perform(&listize); diff --git a/src/remove_placeholders.hpp b/src/remove_placeholders.hpp index 762dd2344c..ed583cddba 100644 --- a/src/remove_placeholders.hpp +++ b/src/remove_placeholders.hpp @@ -17,7 +17,7 @@ namespace Sass { void fallback_impl(AST_Node* n) {} - private: + public: Selector_List* remove_placeholders(Selector_List*); public: