@@ -505,36 +505,28 @@ namespace Sass {
505505 return false;
506506 }
507507
508+ namespace {
509+
510+ int SelectorOrder(Simple_Selector_Ptr sel) {
511+ if (Cast<Element_Selector>(sel)) return 1;
512+ if (Cast<Id_Selector>(sel) || Cast<Class_Selector>(sel)) return 2;
513+ if (Cast<Attribute_Selector>(sel)) return 3;
514+ if (Cast<Pseudo_Selector>(sel)) return Cast<Pseudo_Selector>(sel)->is_pseudo_element() ? 6 : 4;
515+ if (Cast<Wrapped_Selector>(sel)) return 5;
516+ return 7;
517+ }
518+
519+ } // namespace
520+
508521 Compound_Selector_Ptr Simple_Selector::unify_with(Compound_Selector_Ptr rhs)
509522 {
510- for (size_t i = 0, L = rhs->length(); i < L; ++i)
523+ const size_t rsize = rhs->length();
524+ for (size_t i = 0; i < rsize; ++i)
511525 { if (to_string() == rhs->at(i)->to_string()) return rhs; }
512-
513- // check for pseudo elements because they are always last
514- size_t i, L;
515- bool found = false;
516- if (typeid(*this) == typeid(Pseudo_Selector) || typeid(*this) == typeid(Wrapped_Selector) || typeid(*this) == typeid(Attribute_Selector))
517- {
518- for (i = 0, L = rhs->length(); i < L; ++i)
519- {
520- if ((Cast<Pseudo_Selector>((*rhs)[i]) || Cast<Wrapped_Selector>((*rhs)[i]) || Cast<Attribute_Selector>((*rhs)[i])) && (*rhs)[L-1]->is_pseudo_element())
521- { found = true; break; }
522- }
523- }
524- else
525- {
526- for (i = 0, L = rhs->length(); i < L; ++i)
527- {
528- if (Cast<Pseudo_Selector>((*rhs)[i]) || Cast<Wrapped_Selector>((*rhs)[i]) || Cast<Attribute_Selector>((*rhs)[i]))
529- { found = true; break; }
530- }
531- }
532- if (!found)
533- {
534- rhs->append(this);
535- } else {
536- rhs->elements().insert(rhs->elements().begin() + i, this);
537- }
526+ const int lhs_order = SelectorOrder(this);
527+ size_t i = rsize;
528+ while (i > 0 && lhs_order < SelectorOrder(rhs->at(i - 1))) --i;
529+ rhs->elements().insert(rhs->elements().begin() + i, this);
538530 return rhs;
539531 }
540532
0 commit comments