@@ -1711,7 +1711,8 @@ namespace Sass {
1711
1711
static bool complexSelectorHasExtension (
1712
1712
Complex_Selector* pComplexSelector,
1713
1713
Context& ctx,
1714
- ExtensionSubsetMap& subset_map) {
1714
+ ExtensionSubsetMap& subset_map,
1715
+ std::set<Compound_Selector>& seen) {
1715
1716
1716
1717
bool hasExtension = false ;
1717
1718
@@ -1721,16 +1722,18 @@ namespace Sass {
1721
1722
Compound_Selector* pHead = pIter->head ();
1722
1723
1723
1724
if (pHead) {
1724
- for (Simple_Selector* pSimple : *pHead) {
1725
- if (Wrapped_Selector* ws = dynamic_cast <Wrapped_Selector*>(pSimple)) {
1726
- if (Selector_List* sl = dynamic_cast <Selector_List*>(ws->selector ())) {
1727
- for (Complex_Selector* cs : sl->elements ()) {
1728
- while (cs) {
1729
- if (complexSelectorHasExtension (cs, ctx, subset_map)) {
1730
- hasExtension = true ;
1731
- break ;
1725
+ if (seen.find (*pHead) == seen.end ()) {
1726
+ for (Simple_Selector* pSimple : *pHead) {
1727
+ if (Wrapped_Selector* ws = dynamic_cast <Wrapped_Selector*>(pSimple)) {
1728
+ if (Selector_List* sl = dynamic_cast <Selector_List*>(ws->selector ())) {
1729
+ for (Complex_Selector* cs : sl->elements ()) {
1730
+ while (cs) {
1731
+ if (complexSelectorHasExtension (cs, ctx, subset_map, seen)) {
1732
+ hasExtension = true ;
1733
+ break ;
1734
+ }
1735
+ cs = cs->tail ();
1732
1736
}
1733
- cs = cs->tail ();
1734
1737
}
1735
1738
}
1736
1739
}
@@ -1907,6 +1910,14 @@ namespace Sass {
1907
1910
This is the equivalent of ruby's CommaSequence.do_extend.
1908
1911
*/
1909
1912
Selector_List* Extend::extendSelectorList (Selector_List* pSelectorList, Context& ctx, ExtensionSubsetMap& subset_map, bool isReplace, bool & extendedSomething) {
1913
+ std::set<Compound_Selector> seen;
1914
+ return extendSelectorList (pSelectorList, ctx, subset_map, isReplace, extendedSomething, seen);
1915
+ }
1916
+
1917
+ /*
1918
+ This is the equivalent of ruby's CommaSequence.do_extend.
1919
+ */
1920
+ Selector_List* Extend::extendSelectorList (Selector_List* pSelectorList, Context& ctx, ExtensionSubsetMap& subset_map, bool isReplace, bool & extendedSomething, std::set<Compound_Selector>& seen) {
1910
1921
1911
1922
Selector_List* pNewSelectors = SASS_MEMORY_NEW (ctx.mem , Selector_List, pSelectorList->pstate (), pSelectorList->length ());
1912
1923
@@ -1920,19 +1931,18 @@ namespace Sass {
1920
1931
// run through the extend code (which does a data model transformation), check if there is anything to extend before doing
1921
1932
// the extend. We might be able to optimize extendComplexSelector, but this approach keeps us closer to ruby sass (which helps
1922
1933
// when debugging).
1923
- if (!complexSelectorHasExtension (pSelector, ctx, subset_map)) {
1934
+ if (!complexSelectorHasExtension (pSelector, ctx, subset_map, seen )) {
1924
1935
*pNewSelectors << pSelector;
1925
1936
continue ;
1926
1937
}
1927
1938
1928
1939
extendedSomething = true ;
1929
1940
1930
- std::set<Compound_Selector> seen;
1931
-
1932
1941
Node extendedSelectors = extendComplexSelector (pSelector, ctx, subset_map, seen, isReplace, true );
1933
1942
if (!pSelector->has_placeholder ()) {
1934
1943
if (!extendedSelectors.contains (complexSelectorToNode (pSelector, ctx), true /* simpleSelectorOrderDependent*/ )) {
1935
1944
*pNewSelectors << pSelector;
1945
+ continue ;
1936
1946
}
1937
1947
}
1938
1948
@@ -1955,7 +1965,9 @@ namespace Sass {
1955
1965
// process tails
1956
1966
while (cur) {
1957
1967
// process header
1958
- if (cur->head ()) {
1968
+ if (cur->head () && seen.find (*cur->head ()) == seen.end ()) {
1969
+ std::set<Compound_Selector> recseen (seen);
1970
+ recseen.insert (*cur->head ());
1959
1971
// create a copy since we add multiple items if stuff get unwrapped
1960
1972
Compound_Selector* cpy_head = SASS_MEMORY_NEW (ctx.mem , Compound_Selector, cur->pstate ());
1961
1973
for (Simple_Selector* hs : *cur->head ()) {
@@ -1969,14 +1981,19 @@ namespace Sass {
1969
1981
// has wrapped selectors
1970
1982
else {
1971
1983
// extend the inner list of wrapped selector
1972
- Selector_List* ext_sl = extendSelectorList (sl, ctx, subset_map);
1984
+ Selector_List* ext_sl = extendSelectorList (sl, ctx, subset_map, recseen );
1973
1985
for (size_t i = 0 ; i < ext_sl->length (); i += 1 ) {
1974
1986
if (Complex_Selector* ext_cs = ext_sl->at (i)) {
1975
1987
// create clones for wrapped selector and the inner list
1976
1988
Wrapped_Selector* cpy_ws = SASS_MEMORY_NEW (ctx.mem , Wrapped_Selector, *ws);
1977
1989
Selector_List* cpy_ws_sl = SASS_MEMORY_NEW (ctx.mem , Selector_List, sl->pstate ());
1978
1990
// remove parent selectors from inner selector
1979
- if (ext_cs->first ()) *cpy_ws_sl << ext_cs->first ();
1991
+ if (ext_cs->first ()) {
1992
+ if (ext_cs->first ()->has_wrapped_selector ()) {
1993
+ continue ; // ignore this case for now
1994
+ }
1995
+ *cpy_ws_sl << ext_cs->first ();
1996
+ }
1980
1997
// assign list to clone
1981
1998
cpy_ws->selector (cpy_ws_sl);
1982
1999
// append the clone
0 commit comments