diff --git a/src/ast.cpp b/src/ast.cpp index 7e344f81c..d4a7ac0aa 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -505,36 +505,28 @@ namespace Sass { return false; } + namespace { + + int SelectorOrder(Simple_Selector_Ptr sel) { + if (Cast(sel)) return 1; + if (Cast(sel) || Cast(sel)) return 2; + if (Cast(sel)) return 3; + if (Cast(sel)) return Cast(sel)->is_pseudo_element() ? 6 : 4; + if (Cast(sel)) return 5; + return 7; + } + + } // namespace + Compound_Selector_Ptr Simple_Selector::unify_with(Compound_Selector_Ptr rhs) { - for (size_t i = 0, L = rhs->length(); i < L; ++i) + const size_t rsize = rhs->length(); + for (size_t i = 0; i < rsize; ++i) { if (to_string() == rhs->at(i)->to_string()) return rhs; } - - // check for pseudo elements because they are always last - size_t i, L; - bool found = false; - if (typeid(*this) == typeid(Pseudo_Selector) || typeid(*this) == typeid(Wrapped_Selector) || typeid(*this) == typeid(Attribute_Selector)) - { - for (i = 0, L = rhs->length(); i < L; ++i) - { - if ((Cast((*rhs)[i]) || Cast((*rhs)[i]) || Cast((*rhs)[i])) && (*rhs)[L-1]->is_pseudo_element()) - { found = true; break; } - } - } - else - { - for (i = 0, L = rhs->length(); i < L; ++i) - { - if (Cast((*rhs)[i]) || Cast((*rhs)[i]) || Cast((*rhs)[i])) - { found = true; break; } - } - } - if (!found) - { - rhs->append(this); - } else { - rhs->elements().insert(rhs->elements().begin() + i, this); - } + const int lhs_order = SelectorOrder(this); + size_t i = rsize; + while (i > 0 && lhs_order < SelectorOrder(rhs->at(i - 1))) --i; + rhs->elements().insert(rhs->elements().begin() + i, this); return rhs; }