sassc 2.2.1 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -0
  3. data/CHANGELOG.md +18 -0
  4. data/Rakefile +1 -3
  5. data/ext/extconf.rb +13 -5
  6. data/ext/libsass/VERSION +1 -1
  7. data/ext/libsass/include/sass/base.h +2 -1
  8. data/ext/libsass/include/sass/context.h +4 -0
  9. data/ext/libsass/src/MurmurHash2.hpp +91 -0
  10. data/ext/libsass/src/ast.cpp +158 -168
  11. data/ext/libsass/src/ast.hpp +389 -230
  12. data/ext/libsass/src/ast_def_macros.hpp +18 -10
  13. data/ext/libsass/src/ast_fwd_decl.cpp +4 -3
  14. data/ext/libsass/src/ast_fwd_decl.hpp +98 -165
  15. data/ext/libsass/src/ast_helpers.hpp +292 -0
  16. data/ext/libsass/src/ast_sel_cmp.cpp +219 -732
  17. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  18. data/ext/libsass/src/ast_sel_unify.cpp +207 -212
  19. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  20. data/ext/libsass/src/ast_selectors.cpp +594 -1026
  21. data/ext/libsass/src/ast_selectors.hpp +339 -385
  22. data/ext/libsass/src/ast_supports.cpp +36 -52
  23. data/ext/libsass/src/ast_supports.hpp +29 -29
  24. data/ext/libsass/src/ast_values.cpp +271 -84
  25. data/ext/libsass/src/ast_values.hpp +116 -107
  26. data/ext/libsass/src/backtrace.cpp +9 -9
  27. data/ext/libsass/src/backtrace.hpp +5 -5
  28. data/ext/libsass/src/base64vlq.cpp +2 -2
  29. data/ext/libsass/src/base64vlq.hpp +1 -1
  30. data/ext/libsass/src/bind.cpp +18 -18
  31. data/ext/libsass/src/bind.hpp +1 -1
  32. data/ext/libsass/src/c2ast.cpp +3 -3
  33. data/ext/libsass/src/c2ast.hpp +1 -1
  34. data/ext/libsass/src/cencode.c +4 -6
  35. data/ext/libsass/src/check_nesting.cpp +40 -41
  36. data/ext/libsass/src/check_nesting.hpp +6 -2
  37. data/ext/libsass/src/color_maps.cpp +14 -13
  38. data/ext/libsass/src/color_maps.hpp +1 -9
  39. data/ext/libsass/src/constants.cpp +5 -0
  40. data/ext/libsass/src/constants.hpp +6 -0
  41. data/ext/libsass/src/context.cpp +92 -119
  42. data/ext/libsass/src/context.hpp +41 -53
  43. data/ext/libsass/src/cssize.cpp +66 -149
  44. data/ext/libsass/src/cssize.hpp +17 -23
  45. data/ext/libsass/src/dart_helpers.hpp +199 -0
  46. data/ext/libsass/src/debugger.hpp +451 -295
  47. data/ext/libsass/src/emitter.cpp +15 -16
  48. data/ext/libsass/src/emitter.hpp +10 -12
  49. data/ext/libsass/src/environment.cpp +27 -27
  50. data/ext/libsass/src/environment.hpp +29 -24
  51. data/ext/libsass/src/error_handling.cpp +62 -41
  52. data/ext/libsass/src/error_handling.hpp +61 -51
  53. data/ext/libsass/src/eval.cpp +167 -281
  54. data/ext/libsass/src/eval.hpp +27 -29
  55. data/ext/libsass/src/eval_selectors.cpp +75 -0
  56. data/ext/libsass/src/expand.cpp +275 -222
  57. data/ext/libsass/src/expand.hpp +36 -16
  58. data/ext/libsass/src/extender.cpp +1188 -0
  59. data/ext/libsass/src/extender.hpp +399 -0
  60. data/ext/libsass/src/extension.cpp +43 -0
  61. data/ext/libsass/src/extension.hpp +89 -0
  62. data/ext/libsass/src/file.cpp +81 -72
  63. data/ext/libsass/src/file.hpp +28 -37
  64. data/ext/libsass/src/fn_colors.cpp +20 -18
  65. data/ext/libsass/src/fn_lists.cpp +30 -29
  66. data/ext/libsass/src/fn_maps.cpp +3 -3
  67. data/ext/libsass/src/fn_miscs.cpp +34 -46
  68. data/ext/libsass/src/fn_numbers.cpp +20 -13
  69. data/ext/libsass/src/fn_selectors.cpp +98 -128
  70. data/ext/libsass/src/fn_strings.cpp +47 -33
  71. data/ext/libsass/src/fn_utils.cpp +31 -29
  72. data/ext/libsass/src/fn_utils.hpp +17 -11
  73. data/ext/libsass/src/inspect.cpp +186 -148
  74. data/ext/libsass/src/inspect.hpp +31 -29
  75. data/ext/libsass/src/lexer.cpp +20 -82
  76. data/ext/libsass/src/lexer.hpp +5 -16
  77. data/ext/libsass/src/listize.cpp +23 -37
  78. data/ext/libsass/src/listize.hpp +8 -9
  79. data/ext/libsass/src/mapping.hpp +1 -0
  80. data/ext/libsass/src/memory/allocator.cpp +48 -0
  81. data/ext/libsass/src/memory/allocator.hpp +138 -0
  82. data/ext/libsass/src/memory/config.hpp +20 -0
  83. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  84. data/ext/libsass/src/memory/{SharedPtr.cpp → shared_ptr.cpp} +2 -2
  85. data/ext/libsass/src/memory/{SharedPtr.hpp → shared_ptr.hpp} +55 -9
  86. data/ext/libsass/src/memory.hpp +12 -0
  87. data/ext/libsass/src/operation.hpp +71 -61
  88. data/ext/libsass/src/operators.cpp +19 -18
  89. data/ext/libsass/src/operators.hpp +11 -11
  90. data/ext/libsass/src/ordered_map.hpp +112 -0
  91. data/ext/libsass/src/output.cpp +45 -64
  92. data/ext/libsass/src/output.hpp +6 -6
  93. data/ext/libsass/src/parser.cpp +512 -700
  94. data/ext/libsass/src/parser.hpp +89 -97
  95. data/ext/libsass/src/parser_selectors.cpp +189 -0
  96. data/ext/libsass/src/permutate.hpp +164 -0
  97. data/ext/libsass/src/plugins.cpp +7 -7
  98. data/ext/libsass/src/plugins.hpp +8 -8
  99. data/ext/libsass/src/position.cpp +7 -26
  100. data/ext/libsass/src/position.hpp +44 -21
  101. data/ext/libsass/src/prelexer.cpp +6 -6
  102. data/ext/libsass/src/remove_placeholders.cpp +55 -56
  103. data/ext/libsass/src/remove_placeholders.hpp +21 -18
  104. data/ext/libsass/src/sass.cpp +16 -15
  105. data/ext/libsass/src/sass.hpp +10 -5
  106. data/ext/libsass/src/sass2scss.cpp +4 -4
  107. data/ext/libsass/src/sass_context.cpp +91 -122
  108. data/ext/libsass/src/sass_context.hpp +2 -2
  109. data/ext/libsass/src/sass_functions.cpp +1 -1
  110. data/ext/libsass/src/sass_values.cpp +8 -11
  111. data/ext/libsass/src/settings.hpp +19 -0
  112. data/ext/libsass/src/source.cpp +69 -0
  113. data/ext/libsass/src/source.hpp +95 -0
  114. data/ext/libsass/src/source_data.hpp +32 -0
  115. data/ext/libsass/src/source_map.cpp +22 -18
  116. data/ext/libsass/src/source_map.hpp +12 -9
  117. data/ext/libsass/src/stylesheet.cpp +22 -0
  118. data/ext/libsass/src/stylesheet.hpp +57 -0
  119. data/ext/libsass/src/to_value.cpp +2 -2
  120. data/ext/libsass/src/to_value.hpp +1 -1
  121. data/ext/libsass/src/units.cpp +24 -22
  122. data/ext/libsass/src/units.hpp +8 -8
  123. data/ext/libsass/src/utf8_string.cpp +9 -10
  124. data/ext/libsass/src/utf8_string.hpp +7 -6
  125. data/ext/libsass/src/util.cpp +48 -50
  126. data/ext/libsass/src/util.hpp +20 -21
  127. data/ext/libsass/src/util_string.cpp +111 -61
  128. data/ext/libsass/src/util_string.hpp +62 -8
  129. data/ext/libsass/src/values.cpp +12 -12
  130. data/lib/sassc/engine.rb +5 -3
  131. data/lib/sassc/functions_handler.rb +8 -8
  132. data/lib/sassc/native.rb +4 -6
  133. data/lib/sassc/script.rb +4 -4
  134. data/lib/sassc/version.rb +1 -1
  135. data/test/functions_test.rb +18 -1
  136. data/test/native_test.rb +4 -4
  137. metadata +29 -15
  138. data/ext/libsass/src/extend.cpp +0 -2132
  139. data/ext/libsass/src/extend.hpp +0 -86
  140. data/ext/libsass/src/node.cpp +0 -322
  141. data/ext/libsass/src/node.hpp +0 -118
  142. data/ext/libsass/src/paths.hpp +0 -71
  143. data/ext/libsass/src/sass_util.cpp +0 -152
  144. data/ext/libsass/src/sass_util.hpp +0 -256
  145. data/ext/libsass/src/subset_map.cpp +0 -58
  146. data/ext/libsass/src/subset_map.hpp +0 -76
  147. data/lib/sassc/native/lib_c.rb +0 -21
@@ -2,51 +2,17 @@
2
2
  // __EXTENSIONS__ fix on Solaris.
3
3
  #include "sass.hpp"
4
4
 
5
- #include "ast.hpp"
6
- #include "context.hpp"
7
- #include "node.hpp"
8
- #include "eval.hpp"
9
- #include "extend.hpp"
10
- #include "emitter.hpp"
11
- #include "color_maps.hpp"
12
- #include "ast_fwd_decl.hpp"
13
- #include <set>
14
- #include <iomanip>
15
- #include <iostream>
16
- #include <algorithm>
17
- #include <functional>
18
- #include <cctype>
19
- #include <locale>
20
-
21
5
  #include "ast_selectors.hpp"
22
6
 
23
7
  namespace Sass {
24
8
 
25
9
  /*#########################################################################*/
10
+ // Compare against base class on right hand side
11
+ // try to find the most specialized implementation
26
12
  /*#########################################################################*/
27
13
 
28
- bool Selector_List::operator== (const Selector& rhs) const
29
- {
30
- if (auto sl = Cast<Selector_List>(&rhs)) { return *this == *sl; }
31
- else if (auto ss = Cast<Simple_Selector>(&rhs)) { return *this == *ss; }
32
- else if (auto cpx = Cast<Complex_Selector>(&rhs)) { return *this == *cpx; }
33
- else if (auto cpd = Cast<Compound_Selector>(&rhs)) { return *this == *cpd; }
34
- else if (auto ls = Cast<List>(&rhs)) { return *this == *ls; }
35
- throw std::runtime_error("invalid selector base classes to compare");
36
- }
37
-
38
- bool Selector_List::operator< (const Selector& rhs) const
39
- {
40
- if (auto sl = Cast<Selector_List>(&rhs)) { return *this < *sl; }
41
- else if (auto ss = Cast<Simple_Selector>(&rhs)) { return *this < *ss; }
42
- else if (auto cpx = Cast<Complex_Selector>(&rhs)) { return *this < *cpx; }
43
- else if (auto cpd = Cast<Compound_Selector>(&rhs)) { return *this < *cpd; }
44
- else if (auto ls = Cast<List>(&rhs)) { return *this < *ls; }
45
- throw std::runtime_error("invalid selector base classes to compare");
46
- }
47
-
48
14
  // Selector lists can be compared to comma lists
49
- bool Selector_List::operator== (const Expression& rhs) const
15
+ bool SelectorList::operator== (const Expression& rhs) const
50
16
  {
51
17
  if (auto l = Cast<List>(&rhs)) { return *this == *l; }
52
18
  if (auto s = Cast<Selector>(&rhs)) { return *this == *s; }
@@ -55,852 +21,373 @@ namespace Sass {
55
21
  }
56
22
 
57
23
  // Selector lists can be compared to comma lists
58
- bool Selector_List::operator< (const Expression& rhs) const
59
- {
60
- if (auto l = Cast<List>(&rhs)) { return *this < *l; }
61
- if (auto s = Cast<Selector>(&rhs)) { return *this < *s; }
62
- if (Cast<String>(&rhs) || Cast<Null>(&rhs)) { return true; }
63
- throw std::runtime_error("invalid selector base classes to compare");
64
- }
65
-
66
- bool Complex_Selector::operator== (const Selector& rhs) const
67
- {
68
- if (auto sl = Cast<Selector_List>(&rhs)) return *this == *sl;
69
- if (auto ss = Cast<Simple_Selector>(&rhs)) return *this == *ss;
70
- if (auto cs = Cast<Complex_Selector>(&rhs)) return *this == *cs;
71
- if (auto ch = Cast<Compound_Selector>(&rhs)) return *this == *ch;
72
- throw std::runtime_error("invalid selector base classes to compare");
73
- }
74
-
75
- bool Complex_Selector::operator< (const Selector& rhs) const
76
- {
77
- if (auto sl = Cast<Selector_List>(&rhs)) return *this < *sl;
78
- if (auto ss = Cast<Simple_Selector>(&rhs)) return *this < *ss;
79
- if (auto cs = Cast<Complex_Selector>(&rhs)) return *this < *cs;
80
- if (auto ch = Cast<Compound_Selector>(&rhs)) return *this < *ch;
81
- throw std::runtime_error("invalid selector base classes to compare");
82
- }
83
-
84
- bool Compound_Selector::operator== (const Selector& rhs) const
24
+ bool SelectorList::operator== (const Selector& rhs) const
85
25
  {
86
- if (auto sl = Cast<Selector_List>(&rhs)) return *this == *sl;
87
- if (auto ss = Cast<Simple_Selector>(&rhs)) return *this == *ss;
88
- if (auto cs = Cast<Complex_Selector>(&rhs)) return *this == *cs;
89
- if (auto ch = Cast<Compound_Selector>(&rhs)) return *this == *ch;
26
+ if (auto sel = Cast<SelectorList>(&rhs)) { return *this == *sel; }
27
+ if (auto sel = Cast<ComplexSelector>(&rhs)) { return *this == *sel; }
28
+ if (auto sel = Cast<CompoundSelector>(&rhs)) { return *this == *sel; }
29
+ if (auto sel = Cast<SimpleSelector>(&rhs)) { return *this == *sel; }
30
+ if (auto list = Cast<List>(&rhs)) { return *this == *list; }
90
31
  throw std::runtime_error("invalid selector base classes to compare");
91
32
  }
92
33
 
93
- bool Compound_Selector::operator< (const Selector& rhs) const
34
+ bool ComplexSelector::operator== (const Selector& rhs) const
94
35
  {
95
- if (auto sl = Cast<Selector_List>(&rhs)) return *this < *sl;
96
- if (auto ss = Cast<Simple_Selector>(&rhs)) return *this < *ss;
97
- if (auto cs = Cast<Complex_Selector>(&rhs)) return *this < *cs;
98
- if (auto ch = Cast<Compound_Selector>(&rhs)) return *this < *ch;
36
+ if (auto sel = Cast<SelectorList>(&rhs)) { return *this == *sel; }
37
+ if (auto sel = Cast<ComplexSelector>(&rhs)) { return *sel == *this; }
38
+ if (auto sel = Cast<CompoundSelector>(&rhs)) { return *this == *sel; }
39
+ if (auto sel = Cast<SimpleSelector>(&rhs)) { return *this == *sel; }
99
40
  throw std::runtime_error("invalid selector base classes to compare");
100
41
  }
101
42
 
102
- bool Selector_Schema::operator== (const Selector& rhs) const
43
+ bool SelectorCombinator::operator== (const Selector& rhs) const
103
44
  {
104
- if (auto sl = Cast<Selector_List>(&rhs)) return *this == *sl;
105
- if (auto ss = Cast<Simple_Selector>(&rhs)) return *this == *ss;
106
- if (auto cs = Cast<Complex_Selector>(&rhs)) return *this == *cs;
107
- if (auto ch = Cast<Compound_Selector>(&rhs)) return *this == *ch;
108
- throw std::runtime_error("invalid selector base classes to compare");
109
- }
110
-
111
- bool Selector_Schema::operator< (const Selector& rhs) const
112
- {
113
- if (auto sl = Cast<Selector_List>(&rhs)) return *this < *sl;
114
- if (auto ss = Cast<Simple_Selector>(&rhs)) return *this < *ss;
115
- if (auto cs = Cast<Complex_Selector>(&rhs)) return *this < *cs;
116
- if (auto ch = Cast<Compound_Selector>(&rhs)) return *this < *ch;
117
- throw std::runtime_error("invalid selector base classes to compare");
45
+ if (auto cpx = Cast<SelectorCombinator>(&rhs)) { return *this == *cpx; }
46
+ return false;
118
47
  }
119
48
 
120
- bool Simple_Selector::operator== (const Selector& rhs) const
49
+ bool CompoundSelector::operator== (const Selector& rhs) const
121
50
  {
122
- if (auto sl = Cast<Selector_List>(&rhs)) return *this == *sl;
123
- if (auto ss = Cast<Simple_Selector>(&rhs)) return *this == *ss;
124
- if (auto cs = Cast<Complex_Selector>(&rhs)) return *this == *cs;
125
- if (auto ch = Cast<Compound_Selector>(&rhs)) return *this == *ch;
51
+ if (auto sel = Cast<SimpleSelector>(&rhs)) { return *this == *sel; }
52
+ if (auto sel = Cast<SelectorList>(&rhs)) { return *this == *sel; }
53
+ if (auto sel = Cast<ComplexSelector>(&rhs)) { return *this == *sel; }
54
+ if (auto sel = Cast<CompoundSelector>(&rhs)) { return *this == *sel; }
126
55
  throw std::runtime_error("invalid selector base classes to compare");
127
56
  }
128
57
 
129
- bool Simple_Selector::operator< (const Selector& rhs) const
58
+ bool SimpleSelector::operator== (const Selector& rhs) const
130
59
  {
131
- if (auto sl = Cast<Selector_List>(&rhs)) return *this < *sl;
132
- if (auto ss = Cast<Simple_Selector>(&rhs)) return *this < *ss;
133
- if (auto cs = Cast<Complex_Selector>(&rhs)) return *this < *cs;
134
- if (auto ch = Cast<Compound_Selector>(&rhs)) return *this < *ch;
60
+ if (auto sel = Cast<SelectorList>(&rhs)) { return *this == *sel; }
61
+ if (auto sel = Cast<ComplexSelector>(&rhs)) { return *this == *sel; }
62
+ if (auto sel = Cast<CompoundSelector>(&rhs)) { return *this == *sel; }
63
+ if (auto sel = Cast<SimpleSelector>(&rhs)) return *this == *sel;
135
64
  throw std::runtime_error("invalid selector base classes to compare");
136
65
  }
137
66
 
138
67
  /*#########################################################################*/
139
68
  /*#########################################################################*/
140
69
 
141
- bool Selector_List::operator< (const Selector_List& rhs) const
142
- {
143
- size_t l = rhs.length();
144
- if (length() < l) l = length();
145
- for (size_t i = 0; i < l; i ++) {
146
- if (*at(i) < *rhs.at(i)) return true;
147
- if (*at(i) != *rhs.at(i)) return false;
148
- }
149
- return false;
150
- }
151
-
152
- bool Selector_List::operator== (const Selector_List& rhs) const
70
+ bool SelectorList::operator== (const SelectorList& rhs) const
153
71
  {
154
72
  if (&rhs == this) return true;
155
73
  if (rhs.length() != length()) return false;
156
- std::unordered_set<const Complex_Selector *, HashPtr, ComparePtrs> lhs_set;
74
+ std::unordered_set<const ComplexSelector*, PtrObjHash, PtrObjEquality> lhs_set;
157
75
  lhs_set.reserve(length());
158
- for (const Complex_Selector_Obj &element : elements()) {
76
+ for (const ComplexSelectorObj& element : elements()) {
159
77
  lhs_set.insert(element.ptr());
160
78
  }
161
- for (const Complex_Selector_Obj &element : rhs.elements()) {
162
- if (lhs_set.find(element.ptr()) == lhs_set.end()) return false;
163
- }
164
- return true;
165
- }
166
-
167
- bool Compound_Selector::operator< (const Compound_Selector& rhs) const
168
- {
169
- size_t L = std::min(length(), rhs.length());
170
- for (size_t i = 0; i < L; ++i)
171
- {
172
- Simple_Selector* l = (*this)[i];
173
- Simple_Selector* r = rhs[i];
174
- if (!l && !r) return false;
175
- else if (!r) return false;
176
- else if (!l) return true;
177
- else if (*l != *r)
178
- { return *l < *r; }
179
- }
180
- // just compare the length now
181
- return length() < rhs.length();
182
- }
183
-
184
- bool Compound_Selector::operator== (const Compound_Selector& rhs) const
185
- {
186
- if (&rhs == this) return true;
187
- if (rhs.length() != length()) return false;
188
- std::unordered_set<const Simple_Selector *, HashPtr, ComparePtrs> lhs_set;
189
- lhs_set.reserve(length());
190
- for (const Simple_Selector_Obj &element : elements()) {
191
- lhs_set.insert(element.ptr());
192
- }
193
- // there is no break?!
194
- for (const Simple_Selector_Obj &element : rhs.elements()) {
79
+ for (const ComplexSelectorObj& element : rhs.elements()) {
195
80
  if (lhs_set.find(element.ptr()) == lhs_set.end()) return false;
196
81
  }
197
82
  return true;
198
83
  }
199
84
 
200
- bool Complex_Selector::operator< (const Complex_Selector& rhs) const
201
- {
202
- // const iterators for tails
203
- const Complex_Selector* l = this;
204
- const Complex_Selector* r = &rhs;
205
- Compound_Selector* l_h = NULL;
206
- Compound_Selector* r_h = NULL;
207
- if (l) l_h = l->head();
208
- if (r) r_h = r->head();
209
- // process all tails
210
- while (true)
211
- {
212
- #ifdef DEBUG
213
- // skip empty ancestor first
214
- if (l && l->is_empty_ancestor())
215
- {
216
- l_h = NULL;
217
- l = l->tail();
218
- if(l) l_h = l->head();
219
- continue;
220
- }
221
- // skip empty ancestor first
222
- if (r && r->is_empty_ancestor())
223
- {
224
- r_h = NULL;
225
- r = r->tail();
226
- if (r) r_h = r->head();
227
- continue;
228
- }
229
- #endif
230
- // check for valid selectors
231
- if (!l) return !!r;
232
- if (!r) return false;
233
- // both are null
234
- else if (!l_h && !r_h)
235
- {
236
- // check combinator after heads
237
- if (l->combinator() != r->combinator())
238
- { return l->combinator() < r->combinator(); }
239
- // advance to next tails
240
- l = l->tail();
241
- r = r->tail();
242
- // fetch the next headers
243
- l_h = NULL; r_h = NULL;
244
- if (l) l_h = l->head();
245
- if (r) r_h = r->head();
246
- }
247
- // one side is null
248
- else if (!r_h) return true;
249
- else if (!l_h) return false;
250
- // heads ok and equal
251
- else if (*l_h == *r_h)
252
- {
253
- // check combinator after heads
254
- if (l->combinator() != r->combinator())
255
- { return l->combinator() < r->combinator(); }
256
- // advance to next tails
257
- l = l->tail();
258
- r = r->tail();
259
- // fetch the next headers
260
- l_h = NULL; r_h = NULL;
261
- if (l) l_h = l->head();
262
- if (r) r_h = r->head();
263
- }
264
- // heads are not equal
265
- else return *l_h < *r_h;
266
- }
267
- }
268
85
 
269
- bool Complex_Selector::operator== (const Complex_Selector& rhs) const
270
- {
271
- // const iterators for tails
272
- const Complex_Selector* l = this;
273
- const Complex_Selector* r = &rhs;
274
- Compound_Selector* l_h = NULL;
275
- Compound_Selector* r_h = NULL;
276
- if (l) l_h = l->head();
277
- if (r) r_h = r->head();
278
- // process all tails
279
- while (true)
280
- {
281
- // check the pointers
282
- if (!r) return !l;
283
- if (!l) return !r;
284
- // both are null
285
- if (!l_h && !r_h)
286
- {
287
- // check combinator after heads
288
- if (l->combinator() != r->combinator())
289
- { return l->combinator() < r->combinator(); }
290
- // advance to next tails
291
- l = l->tail();
292
- r = r->tail();
293
- // fetch the next heads
294
- l_h = NULL; r_h = NULL;
295
- if (l) l_h = l->head();
296
- if (r) r_h = r->head();
297
- }
298
- // equals if other head is empty
299
- else if ((!l_h && !r_h) ||
300
- (!l_h && r_h->empty()) ||
301
- (!r_h && l_h->empty()) ||
302
- (l_h && r_h && *l_h == *r_h))
303
- {
304
- // check combinator after heads
305
- if (l->combinator() != r->combinator())
306
- { return l->combinator() == r->combinator(); }
307
- // advance to next tails
308
- l = l->tail();
309
- r = r->tail();
310
- // fetch the next heads
311
- l_h = NULL; r_h = NULL;
312
- if (l) l_h = l->head();
313
- if (r) r_h = r->head();
314
- }
315
- // abort
316
- else break;
317
- }
318
- // unreachable
319
- return false;
320
- }
321
86
 
322
87
  /*#########################################################################*/
88
+ // Compare SelectorList against all other selector types
323
89
  /*#########################################################################*/
324
90
 
325
- bool Selector_List::operator== (const Complex_Selector& rhs) const
326
- {
327
- size_t len = length();
328
- if (len > 1) return false;
329
- if (len == 0) return rhs.empty();
330
- return *at(0) == rhs;
331
- }
332
-
333
- bool Selector_List::operator< (const Complex_Selector& rhs) const
91
+ bool SelectorList::operator== (const ComplexSelector& rhs) const
334
92
  {
335
- size_t len = length();
336
- if (len > 1) return false;
337
- if (len == 0) return !rhs.empty();
338
- return *at(0) < rhs;
93
+ // If both are empty they are equal
94
+ if (empty() && rhs.empty()) return true;
95
+ // Must have exactly one item
96
+ if (length() != 1) return false;
97
+ // Compare simple selectors
98
+ return *get(0) == rhs;
339
99
  }
340
100
 
341
- bool Selector_List::operator== (const Compound_Selector& rhs) const
101
+ bool SelectorList::operator== (const CompoundSelector& rhs) const
342
102
  {
343
- size_t len = length();
344
- if (len > 1) return false;
345
- if (len == 0) return rhs.empty();
346
- return *at(0) == rhs;
103
+ // If both are empty they are equal
104
+ if (empty() && rhs.empty()) return true;
105
+ // Must have exactly one item
106
+ if (length() != 1) return false;
107
+ // Compare simple selectors
108
+ return *get(0) == rhs;
347
109
  }
348
110
 
349
- bool Selector_List::operator< (const Compound_Selector& rhs) const
111
+ bool SelectorList::operator== (const SimpleSelector& rhs) const
350
112
  {
351
- size_t len = length();
352
- if (len > 1) return false;
353
- if (len == 0) return !rhs.empty();
354
- return *at(0) < rhs;
113
+ // If both are empty they are equal
114
+ if (empty() && rhs.empty()) return true;
115
+ // Must have exactly one item
116
+ if (length() != 1) return false;
117
+ // Compare simple selectors
118
+ return *get(0) == rhs;
355
119
  }
356
120
 
357
- bool Selector_List::operator== (const Simple_Selector& rhs) const
358
- {
359
- size_t len = length();
360
- if (len > 1) return false;
361
- if (len == 0) return rhs.empty();
362
- return *at(0) == rhs;
363
- }
121
+ /*#########################################################################*/
122
+ // Compare ComplexSelector against itself
123
+ /*#########################################################################*/
364
124
 
365
- bool Selector_List::operator< (const Simple_Selector& rhs) const
125
+ bool ComplexSelector::operator== (const ComplexSelector& rhs) const
366
126
  {
367
127
  size_t len = length();
368
- if (len > 1) return false;
369
- if (len == 0) return !rhs.empty();
370
- return *at(0) < rhs;
371
- }
372
-
373
- /***************************************************************************/
374
- /***************************************************************************/
375
-
376
- bool Complex_Selector::operator== (const Selector_List& rhs) const
377
- {
378
- size_t len = rhs.length();
379
- if (len > 1) return false;
380
- if (len == 0) return empty();
381
- return *this == *rhs.at(0);
382
- }
383
-
384
- bool Complex_Selector::operator< (const Selector_List& rhs) const
385
- {
386
- size_t len = rhs.length();
387
- if (len > 1) return true;
388
- if (len == 0) return false;
389
- return *this < *rhs.at(0);
128
+ size_t rlen = rhs.length();
129
+ if (len != rlen) return false;
130
+ for (size_t i = 0; i < len; i += 1) {
131
+ if (*get(i) != *rhs.get(i)) return false;
132
+ }
133
+ return true;
390
134
  }
391
135
 
392
- bool Complex_Selector::operator== (const Compound_Selector& rhs) const
393
- {
394
- if (tail()) return false;
395
- if (!head()) return rhs.empty();
396
- return *head() == rhs;
397
- }
136
+ /*#########################################################################*/
137
+ // Compare ComplexSelector against all other selector types
138
+ /*#########################################################################*/
398
139
 
399
- bool Complex_Selector::operator< (const Compound_Selector& rhs) const
140
+ bool ComplexSelector::operator== (const SelectorList& rhs) const
400
141
  {
401
- if (tail()) return false;
402
- if (!head()) return !rhs.empty();
403
- return *head() < rhs;
142
+ // If both are empty they are equal
143
+ if (empty() && rhs.empty()) return true;
144
+ // Must have exactly one item
145
+ if (rhs.length() != 1) return false;
146
+ // Compare complex selector
147
+ return *this == *rhs.get(0);
404
148
  }
405
149
 
406
- bool Complex_Selector::operator== (const Simple_Selector& rhs) const
150
+ bool ComplexSelector::operator== (const CompoundSelector& rhs) const
407
151
  {
408
- if (tail()) return false;
409
- if (!head()) return rhs.empty();
410
- return *head() == rhs;
152
+ // If both are empty they are equal
153
+ if (empty() && rhs.empty()) return true;
154
+ // Must have exactly one item
155
+ if (length() != 1) return false;
156
+ // Compare compound selector
157
+ return *get(0) == rhs;
411
158
  }
412
159
 
413
- bool Complex_Selector::operator< (const Simple_Selector& rhs) const
160
+ bool ComplexSelector::operator== (const SimpleSelector& rhs) const
414
161
  {
415
- if (tail()) return false;
416
- if (!head()) return !rhs.empty();
417
- return *head() < rhs;
162
+ // If both are empty they are equal
163
+ if (empty() && rhs.empty()) return true;
164
+ // Must have exactly one item
165
+ if (length() != 1) return false;
166
+ // Compare simple selectors
167
+ return *get(0) == rhs;
418
168
  }
419
169
 
420
- /***************************************************************************/
421
- /***************************************************************************/
170
+ /*#########################################################################*/
171
+ // Compare SelectorCombinator against itself
172
+ /*#########################################################################*/
422
173
 
423
- bool Compound_Selector::operator== (const Selector_List& rhs) const
174
+ bool SelectorCombinator::operator==(const SelectorCombinator& rhs) const
424
175
  {
425
- size_t len = rhs.length();
426
- if (len > 1) return false;
427
- if (len == 0) return empty();
428
- return *this == *rhs.at(0);
176
+ return combinator() == rhs.combinator();
429
177
  }
430
178
 
431
- bool Compound_Selector::operator< (const Selector_List& rhs) const
432
- {
433
- size_t len = rhs.length();
434
- if (len > 1) return true;
435
- if (len == 0) return false;
436
- return *this < *rhs.at(0);
437
- }
179
+ /*#########################################################################*/
180
+ // Compare SelectorCombinator against SelectorComponent
181
+ /*#########################################################################*/
438
182
 
439
- bool Compound_Selector::operator== (const Complex_Selector& rhs) const
183
+ bool SelectorCombinator::operator==(const SelectorComponent& rhs) const
440
184
  {
441
- if (rhs.tail()) return false;
442
- if (!rhs.head()) return empty();
443
- return *this == *rhs.head();
185
+ if (const SelectorCombinator * sel = rhs.getCombinator()) {
186
+ return *this == *sel;
187
+ }
188
+ return false;
444
189
  }
445
190
 
446
- bool Compound_Selector::operator< (const Complex_Selector& rhs) const
191
+ bool CompoundSelector::operator==(const SelectorComponent& rhs) const
447
192
  {
448
- if (rhs.tail()) return true;
449
- if (!rhs.head()) return false;
450
- return *this < *rhs.head();
193
+ if (const CompoundSelector * sel = rhs.getCompound()) {
194
+ return *this == *sel;
195
+ }
196
+ return false;
451
197
  }
452
198
 
453
- bool Compound_Selector::operator< (const Simple_Selector& rhs) const
454
- {
455
- size_t len = length();
456
- if (len > 1) return false;
457
- if (len == 0) return rhs.empty();
458
- return *at(0) == rhs;
459
- }
199
+ /*#########################################################################*/
200
+ // Compare CompoundSelector against itself
201
+ /*#########################################################################*/
202
+ // ToDo: Verifiy implementation
203
+ /*#########################################################################*/
460
204
 
461
- bool Compound_Selector::operator== (const Simple_Selector& rhs) const
205
+ bool CompoundSelector::operator== (const CompoundSelector& rhs) const
462
206
  {
463
- size_t len = length();
464
- if (len > 1) return false;
465
- if (len == 0) return !rhs.empty();
466
- return *at(0) < rhs;
207
+ // std::cerr << "comp vs comp\n";
208
+ if (&rhs == this) return true;
209
+ if (rhs.length() != length()) return false;
210
+ std::unordered_set<const SimpleSelector*, PtrObjHash, PtrObjEquality> lhs_set;
211
+ lhs_set.reserve(length());
212
+ for (const SimpleSelectorObj& element : elements()) {
213
+ lhs_set.insert(element.ptr());
214
+ }
215
+ // there is no break?!
216
+ for (const SimpleSelectorObj& element : rhs.elements()) {
217
+ if (lhs_set.find(element.ptr()) == lhs_set.end()) return false;
218
+ }
219
+ return true;
467
220
  }
468
221
 
469
- /***************************************************************************/
470
- /***************************************************************************/
471
222
 
472
- bool Simple_Selector::operator== (const Selector_List& rhs) const
473
- {
474
- return rhs.length() == 1 && *this == *rhs.at(0);
475
- }
223
+ /*#########################################################################*/
224
+ // Compare CompoundSelector against all other selector types
225
+ /*#########################################################################*/
476
226
 
477
- bool Simple_Selector::operator< (const Selector_List& rhs) const
227
+ bool CompoundSelector::operator== (const SelectorList& rhs) const
478
228
  {
479
- size_t len = rhs.length();
480
- if (len > 1) return true;
481
- if (len == 0) return false;
482
- return *this < *rhs.at(0);
229
+ // If both are empty they are equal
230
+ if (empty() && rhs.empty()) return true;
231
+ // Must have exactly one item
232
+ if (rhs.length() != 1) return false;
233
+ // Compare complex selector
234
+ return *this == *rhs.get(0);
483
235
  }
484
236
 
485
- bool Simple_Selector::operator== (const Complex_Selector& rhs) const
237
+ bool CompoundSelector::operator== (const ComplexSelector& rhs) const
486
238
  {
487
- return !rhs.tail() && rhs.head() &&
488
- rhs.combinator() == Complex_Selector::ANCESTOR_OF &&
489
- *this == *rhs.head();
239
+ // If both are empty they are equal
240
+ if (empty() && rhs.empty()) return true;
241
+ // Must have exactly one item
242
+ if (rhs.length() != 1) return false;
243
+ // Compare compound selector
244
+ return *this == *rhs.get(0);
490
245
  }
491
246
 
492
- bool Simple_Selector::operator< (const Complex_Selector& rhs) const
247
+ bool CompoundSelector::operator== (const SimpleSelector& rhs) const
493
248
  {
494
- if (rhs.tail()) return true;
495
- if (!rhs.head()) return false;
496
- return *this < *rhs.head();
249
+ // If both are empty they are equal
250
+ if (empty() && rhs.empty()) return false;
251
+ // Must have exactly one item
252
+ size_t rlen = length();
253
+ if (rlen > 1) return false;
254
+ if (rlen == 0) return true;
255
+ // Compare simple selectors
256
+ return *get(0) < rhs;
497
257
  }
498
258
 
499
- bool Simple_Selector::operator== (const Compound_Selector& rhs) const
500
- {
501
- return rhs.length() == 1 && *this == *rhs.at(0);
502
- }
259
+ /*#########################################################################*/
260
+ // Compare SimpleSelector against itself (upcast from abstract base)
261
+ /*#########################################################################*/
503
262
 
504
- bool Simple_Selector::operator< (const Compound_Selector& rhs) const
505
- {
506
- size_t len = rhs.length();
507
- if (len > 1) return true;
508
- if (len == 0) return false;
509
- return *this < *rhs.at(0);
510
- }
263
+ // DOES NOT EXIST FOR ABSTRACT BASE CLASS
511
264
 
512
265
  /*#########################################################################*/
266
+ // Compare SimpleSelector against all other selector types
513
267
  /*#########################################################################*/
514
268
 
515
- bool Simple_Selector::operator== (const Simple_Selector& rhs) const
516
- {
517
- switch (simple_type()) {
518
- case ID_SEL: return (const Id_Selector&) *this == rhs; break;
519
- case TYPE_SEL: return (const Type_Selector&) *this == rhs; break;
520
- case CLASS_SEL: return (const Class_Selector&) *this == rhs; break;
521
- case PARENT_SEL: return (const Parent_Selector&) *this == rhs; break;
522
- case PSEUDO_SEL: return (const Pseudo_Selector&) *this == rhs; break;
523
- case WRAPPED_SEL: return (const Wrapped_Selector&) *this == rhs; break;
524
- case ATTRIBUTE_SEL: return (const Attribute_Selector&) *this == rhs; break;
525
- case PLACEHOLDER_SEL: return (const Placeholder_Selector&) *this == rhs; break;
526
- }
527
- return false;
269
+ bool SimpleSelector::operator== (const SelectorList& rhs) const
270
+ {
271
+ // If both are empty they are equal
272
+ if (empty() && rhs.empty()) return true;
273
+ // Must have exactly one item
274
+ if (rhs.length() != 1) return false;
275
+ // Compare complex selector
276
+ return *this == *rhs.get(0);
528
277
  }
529
278
 
530
- /***************************************************************************/
531
- /***************************************************************************/
532
-
533
- bool Id_Selector::operator== (const Simple_Selector& rhs) const
279
+ bool SimpleSelector::operator== (const ComplexSelector& rhs) const
534
280
  {
535
- auto sel = Cast<Id_Selector>(&rhs);
536
- return sel ? *this == *sel : false;
281
+ // If both are empty they are equal
282
+ if (empty() && rhs.empty()) return true;
283
+ // Must have exactly one item
284
+ if (rhs.length() != 1) return false;
285
+ // Compare compound selector
286
+ return *this == *rhs.get(0);
537
287
  }
538
288
 
539
- bool Type_Selector::operator== (const Simple_Selector& rhs) const
289
+ bool SimpleSelector::operator== (const CompoundSelector& rhs) const
540
290
  {
541
- auto sel = Cast<Type_Selector>(&rhs);
542
- return sel ? *this == *sel : false;
291
+ // If both are empty they are equal
292
+ if (empty() && rhs.empty()) return false;
293
+ // Must have exactly one item
294
+ if (rhs.length() != 1) return false;
295
+ // Compare simple selector
296
+ return *this == *rhs.get(0);
543
297
  }
544
298
 
545
- bool Class_Selector::operator== (const Simple_Selector& rhs) const
299
+ /*#########################################################################*/
300
+ /*#########################################################################*/
301
+
302
+ bool IDSelector::operator== (const SimpleSelector& rhs) const
546
303
  {
547
- auto sel = Cast<Class_Selector>(&rhs);
304
+ auto sel = Cast<IDSelector>(&rhs);
548
305
  return sel ? *this == *sel : false;
549
306
  }
550
307
 
551
- bool Parent_Selector::operator== (const Simple_Selector& rhs) const
308
+ bool TypeSelector::operator== (const SimpleSelector& rhs) const
552
309
  {
553
- auto sel = Cast<Parent_Selector>(&rhs);
310
+ auto sel = Cast<TypeSelector>(&rhs);
554
311
  return sel ? *this == *sel : false;
555
312
  }
556
313
 
557
- bool Pseudo_Selector::operator== (const Simple_Selector& rhs) const
314
+ bool ClassSelector::operator== (const SimpleSelector& rhs) const
558
315
  {
559
- auto sel = Cast<Pseudo_Selector>(&rhs);
316
+ auto sel = Cast<ClassSelector>(&rhs);
560
317
  return sel ? *this == *sel : false;
561
318
  }
562
319
 
563
- bool Wrapped_Selector::operator== (const Simple_Selector& rhs) const
320
+ bool PseudoSelector::operator== (const SimpleSelector& rhs) const
564
321
  {
565
- auto sel = Cast<Wrapped_Selector>(&rhs);
322
+ auto sel = Cast<PseudoSelector>(&rhs);
566
323
  return sel ? *this == *sel : false;
567
324
  }
568
325
 
569
- bool Attribute_Selector::operator== (const Simple_Selector& rhs) const
326
+ bool AttributeSelector::operator== (const SimpleSelector& rhs) const
570
327
  {
571
- auto sel = Cast<Attribute_Selector>(&rhs);
328
+ auto sel = Cast<AttributeSelector>(&rhs);
572
329
  return sel ? *this == *sel : false;
573
330
  }
574
331
 
575
- bool Placeholder_Selector::operator== (const Simple_Selector& rhs) const
332
+ bool PlaceholderSelector::operator== (const SimpleSelector& rhs) const
576
333
  {
577
- auto sel = Cast<Placeholder_Selector>(&rhs);
334
+ auto sel = Cast<PlaceholderSelector>(&rhs);
578
335
  return sel ? *this == *sel : false;
579
336
  }
580
337
 
581
- /***************************************************************************/
582
- /***************************************************************************/
338
+ /*#########################################################################*/
339
+ /*#########################################################################*/
583
340
 
584
- bool Id_Selector::operator== (const Id_Selector& rhs) const
341
+ bool IDSelector::operator== (const IDSelector& rhs) const
585
342
  {
586
343
  // ID has no namespacing
587
344
  return name() == rhs.name();
588
345
  }
589
346
 
590
- bool Type_Selector::operator== (const Type_Selector& rhs) const
347
+ bool TypeSelector::operator== (const TypeSelector& rhs) const
591
348
  {
592
349
  return is_ns_eq(rhs) && name() == rhs.name();
593
350
  }
594
351
 
595
- bool Class_Selector::operator== (const Class_Selector& rhs) const
352
+ bool ClassSelector::operator== (const ClassSelector& rhs) const
596
353
  {
597
354
  // Class has no namespacing
598
355
  return name() == rhs.name();
599
356
  }
600
357
 
601
- bool Parent_Selector::operator== (const Parent_Selector& rhs) const
602
- {
603
- // Parent has no namespacing
604
- return name() == rhs.name();
605
- }
606
-
607
- bool Pseudo_Selector::operator== (const Pseudo_Selector& rhs) const
608
- {
609
- std::string lname = name();
610
- std::string rname = rhs.name();
611
- if (is_pseudo_class_element(lname)) {
612
- if (rname[0] == ':' && rname[1] == ':') {
613
- lname = lname.substr(1, std::string::npos);
614
- }
615
- }
616
- // right hand is special pseudo (single colon)
617
- if (is_pseudo_class_element(rname)) {
618
- if (lname[0] == ':' && lname[1] == ':') {
619
- lname = lname.substr(1, std::string::npos);
620
- }
621
- }
622
- // Pseudo has no namespacing
623
- if (lname != rname) return false;
624
- String_Obj lhs_ex = expression();
625
- String_Obj rhs_ex = rhs.expression();
626
- if (rhs_ex && lhs_ex) return *lhs_ex == *rhs_ex;
627
- else return lhs_ex.ptr() == rhs_ex.ptr();
628
- }
629
-
630
- bool Wrapped_Selector::operator== (const Wrapped_Selector& rhs) const
631
- {
632
- // Wrapped has no namespacing
633
- if (name() != rhs.name()) return false;
634
- return *(selector()) == *(rhs.selector());
635
- }
636
-
637
- bool Attribute_Selector::operator== (const Attribute_Selector& rhs) const
638
- {
639
- // get optional value state
640
- bool no_lhs_val = value().isNull();
641
- bool no_rhs_val = rhs.value().isNull();
642
- // both are null, therefore equal
643
- if (no_lhs_val && no_rhs_val) {
644
- return (name() == rhs.name())
645
- && (matcher() == rhs.matcher())
646
- && (is_ns_eq(rhs));
647
- }
648
- // both are defined, evaluate
649
- if (no_lhs_val == no_rhs_val) {
650
- return (name() == rhs.name())
651
- && (matcher() == rhs.matcher())
652
- && (is_ns_eq(rhs))
653
- && (*value() == *rhs.value());
654
- }
655
- // not equal
656
- return false;
657
- }
658
-
659
- bool Placeholder_Selector::operator== (const Placeholder_Selector& rhs) const
358
+ bool PlaceholderSelector::operator== (const PlaceholderSelector& rhs) const
660
359
  {
661
360
  // Placeholder has no namespacing
662
361
  return name() == rhs.name();
663
362
  }
664
363
 
665
- /*#########################################################################*/
666
- /*#########################################################################*/
667
-
668
- bool Simple_Selector::operator< (const Simple_Selector& rhs) const
669
- {
670
- switch (simple_type()) {
671
- case ID_SEL: return (const Id_Selector&) *this < rhs; break;
672
- case TYPE_SEL: return (const Type_Selector&) *this < rhs; break;
673
- case CLASS_SEL: return (const Class_Selector&) *this < rhs; break;
674
- case PARENT_SEL: return (const Parent_Selector&) *this < rhs; break;
675
- case PSEUDO_SEL: return (const Pseudo_Selector&) *this < rhs; break;
676
- case WRAPPED_SEL: return (const Wrapped_Selector&) *this < rhs; break;
677
- case ATTRIBUTE_SEL: return (const Attribute_Selector&) *this < rhs; break;
678
- case PLACEHOLDER_SEL: return (const Placeholder_Selector&) *this < rhs; break;
679
- }
680
- return false;
681
- }
682
-
683
- /***************************************************************************/
684
- /***************************************************************************/
685
-
686
- bool Id_Selector::operator< (const Simple_Selector& rhs) const
687
- {
688
- switch (rhs.simple_type()) {
689
- case TYPE_SEL: return '#' < 's'; break;
690
- case CLASS_SEL: return '#' < '.'; break;
691
- case PARENT_SEL: return '#' < '&'; break;
692
- case PSEUDO_SEL: return '#' < ':'; break;
693
- case WRAPPED_SEL: return '#' < '('; break;
694
- case ATTRIBUTE_SEL: return '#' < '['; break;
695
- case PLACEHOLDER_SEL: return '#' < '%'; break;
696
- case ID_SEL: /* let if fall through */ break;
697
- }
698
- const Id_Selector& sel =
699
- (const Id_Selector&) rhs;
700
- return *this < sel;
701
- }
702
-
703
- bool Type_Selector::operator< (const Simple_Selector& rhs) const
704
- {
705
- switch (rhs.simple_type()) {
706
- case ID_SEL: return 'e' < '#'; break;
707
- case CLASS_SEL: return 'e' < '.'; break;
708
- case PARENT_SEL: return 'e' < '&'; break;
709
- case PSEUDO_SEL: return 'e' < ':'; break;
710
- case WRAPPED_SEL: return 'e' < '('; break;
711
- case ATTRIBUTE_SEL: return 'e' < '['; break;
712
- case PLACEHOLDER_SEL: return 'e' < '%'; break;
713
- case TYPE_SEL: /* let if fall through */ break;
714
- }
715
- const Type_Selector& sel =
716
- (const Type_Selector&) rhs;
717
- return *this < sel;
718
- }
719
-
720
- bool Class_Selector::operator< (const Simple_Selector& rhs) const
721
- {
722
- switch (rhs.simple_type()) {
723
- case ID_SEL: return '.' < '#'; break;
724
- case TYPE_SEL: return '.' < 's'; break;
725
- case PARENT_SEL: return '.' < '&'; break;
726
- case PSEUDO_SEL: return '.' < ':'; break;
727
- case WRAPPED_SEL: return '.' < '('; break;
728
- case ATTRIBUTE_SEL: return '.' < '['; break;
729
- case PLACEHOLDER_SEL: return '.' < '%'; break;
730
- case CLASS_SEL: /* let if fall through */ break;
731
- }
732
- const Class_Selector& sel =
733
- (const Class_Selector&) rhs;
734
- return *this < sel;
735
- }
736
-
737
- bool Pseudo_Selector::operator< (const Simple_Selector& rhs) const
738
- {
739
- switch (rhs.simple_type()) {
740
- case ID_SEL: return ':' < '#'; break;
741
- case TYPE_SEL: return ':' < 's'; break;
742
- case CLASS_SEL: return ':' < '.'; break;
743
- case PARENT_SEL: return ':' < '&'; break;
744
- case WRAPPED_SEL: return ':' < '('; break;
745
- case ATTRIBUTE_SEL: return ':' < '['; break;
746
- case PLACEHOLDER_SEL: return ':' < '%'; break;
747
- case PSEUDO_SEL: /* let if fall through */ break;
748
- }
749
- const Pseudo_Selector& sel =
750
- (const Pseudo_Selector&) rhs;
751
- return *this < sel;
752
- }
753
-
754
- bool Wrapped_Selector::operator< (const Simple_Selector& rhs) const
755
- {
756
- switch (rhs.simple_type()) {
757
- case ID_SEL: return '(' < '#'; break;
758
- case TYPE_SEL: return '(' < 's'; break;
759
- case CLASS_SEL: return '(' < '.'; break;
760
- case PARENT_SEL: return '(' < '&'; break;
761
- case PSEUDO_SEL: return '(' < ':'; break;
762
- case ATTRIBUTE_SEL: return '(' < '['; break;
763
- case PLACEHOLDER_SEL: return '(' < '%'; break;
764
- case WRAPPED_SEL: /* let if fall through */ break;
765
- }
766
- const Wrapped_Selector& sel =
767
- (const Wrapped_Selector&) rhs;
768
- return *this < sel;
769
- }
770
-
771
- bool Parent_Selector::operator< (const Simple_Selector& rhs) const
772
- {
773
- switch (rhs.simple_type()) {
774
- case ID_SEL: return '&' < '#'; break;
775
- case TYPE_SEL: return '&' < 's'; break;
776
- case CLASS_SEL: return '&' < '.'; break;
777
- case PSEUDO_SEL: return '&' < ':'; break;
778
- case WRAPPED_SEL: return '&' < '('; break;
779
- case ATTRIBUTE_SEL: return '&' < '['; break;
780
- case PLACEHOLDER_SEL: return '&' < '%'; break;
781
- case PARENT_SEL: /* let if fall through */ break;
782
- }
783
- const Parent_Selector& sel =
784
- (const Parent_Selector&) rhs;
785
- return *this < sel;
786
- }
787
-
788
- bool Attribute_Selector::operator< (const Simple_Selector& rhs) const
789
- {
790
- switch (rhs.simple_type()) {
791
- case ID_SEL: return '[' < '#'; break;
792
- case TYPE_SEL: return '[' < 'e'; break;
793
- case CLASS_SEL: return '[' < '.'; break;
794
- case PARENT_SEL: return '[' < '&'; break;
795
- case PSEUDO_SEL: return '[' < ':'; break;
796
- case WRAPPED_SEL: return '[' < '('; break;
797
- case PLACEHOLDER_SEL: return '[' < '%'; break;
798
- case ATTRIBUTE_SEL: /* let if fall through */ break;
799
- }
800
- const Attribute_Selector& sel =
801
- (const Attribute_Selector&) rhs;
802
- return *this < sel;
803
- }
804
-
805
- bool Placeholder_Selector::operator< (const Simple_Selector& rhs) const
806
- {
807
- switch (rhs.simple_type()) {
808
- case ID_SEL: return '%' < '#'; break;
809
- case TYPE_SEL: return '%' < 's'; break;
810
- case CLASS_SEL: return '%' < '.'; break;
811
- case PARENT_SEL: return '%' < '&'; break;
812
- case PSEUDO_SEL: return '%' < ':'; break;
813
- case WRAPPED_SEL: return '%' < '('; break;
814
- case ATTRIBUTE_SEL: return '%' < '['; break;
815
- case PLACEHOLDER_SEL: /* let if fall through */ break;
816
- }
817
- const Placeholder_Selector& sel =
818
- (const Placeholder_Selector&) rhs;
819
- return *this < sel;
820
- }
821
-
822
- /***************************************************************************/
823
- /***************************************************************************/
824
-
825
- bool Id_Selector::operator< (const Id_Selector& rhs) const
826
- {
827
- // ID has no namespacing
828
- return name() < rhs.name();
829
- }
830
-
831
- bool Type_Selector::operator< (const Type_Selector& rhs) const
832
- {
833
- return has_ns_ == rhs.has_ns_
834
- ? (ns_ == rhs.ns_
835
- ? name_ < rhs.name_
836
- : ns_ < rhs.ns_)
837
- : has_ns_ < rhs.has_ns_;
838
- }
839
-
840
- bool Class_Selector::operator< (const Class_Selector& rhs) const
364
+ bool AttributeSelector::operator== (const AttributeSelector& rhs) const
841
365
  {
842
- // Class has no namespacing
843
- return name() < rhs.name();
844
- }
845
-
846
- bool Parent_Selector::operator< (const Parent_Selector& rhs) const
847
- {
848
- // Parent has no namespacing
849
- return name() < rhs.name();
850
- }
851
-
852
- bool Pseudo_Selector::operator< (const Pseudo_Selector& rhs) const
853
- {
854
- std::string lname = name();
855
- std::string rname = rhs.name();
856
- if (is_pseudo_class_element(lname)) {
857
- if (rname[0] == ':' && rname[1] == ':') {
858
- lname = lname.substr(1, std::string::npos);
859
- }
860
- }
861
- // right hand is special pseudo (single colon)
862
- if (is_pseudo_class_element(rname)) {
863
- if (lname[0] == ':' && lname[1] == ':') {
864
- lname = lname.substr(1, std::string::npos);
865
- }
366
+ // smaller return, equal go on, bigger abort
367
+ if (is_ns_eq(rhs)) {
368
+ if (name() != rhs.name()) return false;
369
+ if (matcher() != rhs.matcher()) return false;
370
+ if (modifier() != rhs.modifier()) return false;
371
+ const String* lhs_val = value();
372
+ const String* rhs_val = rhs.value();
373
+ return PtrObjEquality()(lhs_val, rhs_val);
866
374
  }
867
- // Peudo has no namespacing
868
- if (lname != rname)
869
- { return lname < rname; }
870
- String_Obj lhs_ex = expression();
871
- String_Obj rhs_ex = rhs.expression();
872
- if (rhs_ex && lhs_ex) return *lhs_ex < *rhs_ex;
873
- else return lhs_ex.ptr() < rhs_ex.ptr();
874
- }
875
-
876
- bool Wrapped_Selector::operator< (const Wrapped_Selector& rhs) const
877
- {
878
- // Wrapped has no namespacing
879
- if (name() != rhs.name())
880
- { return name() < rhs.name(); }
881
- return *(selector()) < *(rhs.selector());
375
+ else { return false; }
882
376
  }
883
377
 
884
- bool Attribute_Selector::operator< (const Attribute_Selector& rhs) const
378
+ bool PseudoSelector::operator== (const PseudoSelector& rhs) const
885
379
  {
886
380
  if (is_ns_eq(rhs)) {
887
- if (name() != rhs.name())
888
- { return name() < rhs.name(); }
889
- if (matcher() != rhs.matcher())
890
- { return matcher() < rhs.matcher(); }
891
- bool no_lhs_val = value().isNull();
892
- bool no_rhs_val = rhs.value().isNull();
893
- if (no_lhs_val && no_rhs_val) return false; // equal
894
- else if (no_lhs_val) return true; // lhs is null
895
- else if (no_rhs_val) return false; // rhs is null
896
- return *value() < *rhs.value(); // both are given
897
- } else { return ns() < rhs.ns(); }
898
- }
899
-
900
- bool Placeholder_Selector::operator< (const Placeholder_Selector& rhs) const
901
- {
902
- // Placeholder has no namespacing
903
- return name() < rhs.name();
381
+ if (name() != rhs.name()) return false;
382
+ if (isElement() != rhs.isElement()) return false;
383
+ const String* lhs_arg = argument();
384
+ const String* rhs_arg = rhs.argument();
385
+ if (!PtrObjEquality()(lhs_arg, rhs_arg)) return false;
386
+ const SelectorList* lhs_sel = selector();
387
+ const SelectorList* rhs_sel = rhs.selector();
388
+ return PtrObjEquality()(lhs_sel, rhs_sel);
389
+ }
390
+ else { return false; }
904
391
  }
905
392
 
906
393
  /*#########################################################################*/