Skip to content

Commit

Permalink
Add and use a unification_order method
Browse files Browse the repository at this point in the history
  • Loading branch information
glebm authored and xzyfer committed Nov 19, 2018
1 parent 3364372 commit 3e60b12
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 15 deletions.
17 changes: 2 additions & 15 deletions src/ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,27 +505,14 @@ namespace Sass {
return false;
}

namespace {

int SelectorOrder(Simple_Selector_Ptr sel) {
if (Cast<Element_Selector>(sel)) return 1;
if (Cast<Id_Selector>(sel) || Cast<Class_Selector>(sel)) return 2;
if (Cast<Attribute_Selector>(sel)) return 3;
if (Cast<Pseudo_Selector>(sel)) return Cast<Pseudo_Selector>(sel)->is_pseudo_element() ? 6 : 4;
if (Cast<Wrapped_Selector>(sel)) return 5;
return 7;
}

} // namespace

Compound_Selector_Ptr Simple_Selector::unify_with(Compound_Selector_Ptr rhs)
{
const size_t rsize = rhs->length();
for (size_t i = 0; i < rsize; ++i)
{ if (to_string() == rhs->at(i)->to_string()) return rhs; }
const int lhs_order = SelectorOrder(this);
const int lhs_order = this->unification_order();
size_t i = rsize;
while (i > 0 && lhs_order < SelectorOrder(rhs->at(i - 1))) --i;
while (i > 0 && lhs_order < rhs->at(i - 1)->unification_order()) --i;
rhs->elements().insert(rhs->elements().begin() + i, this);
return rhs;
}
Expand Down
47 changes: 47 additions & 0 deletions src/ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2215,6 +2215,7 @@ namespace Sass {
virtual ~Selector() = 0;
virtual size_t hash() = 0;
virtual unsigned long specificity() const = 0;
virtual int unification_order() const = 0;
virtual void set_media_block(Media_Block_Ptr mb) {
media_block(mb);
}
Expand Down Expand Up @@ -2394,6 +2395,10 @@ namespace Sass {
{
return 0;
}
int unification_order() const
{
throw std::runtime_error("unification_order for Parent_Selector is undefined");
}
std::string type() const { return "selector"; }
static std::string type_name() { return "selector"; }
ATTACH_AST_OPERATIONS(Parent_Selector)
Expand Down Expand Up @@ -2433,6 +2438,10 @@ namespace Sass {
{
return Constants::Specificity_Base;
}
int unification_order() const
{
return Constants::UnificationOrder_Placeholder;
}
virtual bool has_placeholder() {
return true;
}
Expand All @@ -2457,6 +2466,10 @@ namespace Sass {
if (name() == "*") return 0;
else return Constants::Specificity_Element;
}
int unification_order() const
{
return Constants::UnificationOrder_Element;
}
virtual Simple_Selector_Ptr unify_with(Simple_Selector_Ptr);
virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr);
virtual bool operator==(const Simple_Selector& rhs) const;
Expand All @@ -2482,6 +2495,10 @@ namespace Sass {
{
return Constants::Specificity_Class;
}
int unification_order() const
{
return Constants::UnificationOrder_Class;
}
virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr);
ATTACH_AST_OPERATIONS(Class_Selector)
ATTACH_CRTP_PERFORM_METHODS()
Expand All @@ -2502,6 +2519,10 @@ namespace Sass {
{
return Constants::Specificity_ID;
}
int unification_order() const
{
return Constants::UnificationOrder_Id;
}
virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr);
ATTACH_AST_OPERATIONS(Id_Selector)
ATTACH_CRTP_PERFORM_METHODS()
Expand Down Expand Up @@ -2538,6 +2559,10 @@ namespace Sass {
{
return Constants::Specificity_Attr;
}
int unification_order() const
{
return Constants::UnificationOrder_Attribute;
}
virtual bool operator==(const Simple_Selector& rhs) const;
virtual bool operator==(const Attribute_Selector& rhs) const;
virtual bool operator<(const Simple_Selector& rhs) const;
Expand Down Expand Up @@ -2599,6 +2624,12 @@ namespace Sass {
return Constants::Specificity_Element;
return Constants::Specificity_Pseudo;
}
int unification_order() const
{
if (is_pseudo_element())
return Constants::UnificationOrder_PseudoElement;
return Constants::UnificationOrder_PseudoClass;
}
virtual bool operator==(const Simple_Selector& rhs) const;
virtual bool operator==(const Pseudo_Selector& rhs) const;
virtual bool operator<(const Simple_Selector& rhs) const;
Expand Down Expand Up @@ -2627,6 +2658,10 @@ namespace Sass {
virtual bool has_parent_ref() const;
virtual bool has_real_parent_ref() const;
virtual unsigned long specificity() const;
int unification_order() const
{
return Constants::UnificationOrder_Wrapped;
}
virtual bool find ( bool (*f)(AST_Node_Obj) );
virtual bool operator==(const Simple_Selector& rhs) const;
virtual bool operator==(const Wrapped_Selector& rhs) const;
Expand Down Expand Up @@ -2709,6 +2744,10 @@ namespace Sass {
{ sum += (*this)[i]->specificity(); }
return sum;
}
int unification_order() const
{
throw std::runtime_error("unification_order for Compound_Selector is undefined");
}

virtual bool has_placeholder()
{
Expand Down Expand Up @@ -2837,6 +2876,10 @@ namespace Sass {
if (tail()) sum += tail()->specificity();
return sum;
}
int unification_order() const
{
throw std::runtime_error("unification_order for Complex_Selector is undefined");
}
virtual void set_media_block(Media_Block_Ptr mb) {
media_block(mb);
if (tail_) tail_->set_media_block(mb);
Expand Down Expand Up @@ -2960,6 +3003,10 @@ namespace Sass {
}
return sum;
}
int unification_order() const
{
throw std::runtime_error("unification_order for Selector_List is undefined");
}
virtual void set_media_block(Media_Block_Ptr mb) {
media_block(mb);
for (Complex_Selector_Obj cs : elements()) {
Expand Down
9 changes: 9 additions & 0 deletions src/constants.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ namespace Sass {
extern const unsigned long Specificity_Pseudo = 1000;
extern const unsigned long Specificity_ID = 1000000;

extern const int UnificationOrder_Element = 1;
extern const int UnificationOrder_Id = 2;
extern const int UnificationOrder_Class = 2;
extern const int UnificationOrder_Attribute = 3;
extern const int UnificationOrder_PseudoClass = 4;
extern const int UnificationOrder_Wrapped = 5;
extern const int UnificationOrder_PseudoElement = 6;
extern const int UnificationOrder_Placeholder = 7;

// sass keywords
extern const char at_root_kwd[] = "@at-root";
extern const char import_kwd[] = "@import";
Expand Down
10 changes: 10 additions & 0 deletions src/constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ namespace Sass {
extern const unsigned long Specificity_Pseudo;
extern const unsigned long Specificity_ID;

// Selector unification order;
extern const int UnificationOrder_Element;
extern const int UnificationOrder_Id;
extern const int UnificationOrder_Class;
extern const int UnificationOrder_Attribute;
extern const int UnificationOrder_PseudoClass;
extern const int UnificationOrder_Wrapped;
extern const int UnificationOrder_PseudoElement;
extern const int UnificationOrder_Placeholder;

// sass keywords
extern const char at_root_kwd[];
extern const char import_kwd[];
Expand Down

0 comments on commit 3e60b12

Please sign in to comment.