sassc 2.2.1 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/CHANGELOG.md +13 -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 +1 -0
  9. data/ext/libsass/src/ast.cpp +49 -59
  10. data/ext/libsass/src/ast.hpp +263 -102
  11. data/ext/libsass/src/ast_def_macros.hpp +8 -0
  12. data/ext/libsass/src/ast_fwd_decl.cpp +2 -1
  13. data/ext/libsass/src/ast_fwd_decl.hpp +40 -116
  14. data/ext/libsass/src/ast_helpers.hpp +292 -0
  15. data/ext/libsass/src/ast_sel_cmp.cpp +209 -722
  16. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  17. data/ext/libsass/src/ast_sel_unify.cpp +207 -212
  18. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  19. data/ext/libsass/src/ast_selectors.cpp +559 -1001
  20. data/ext/libsass/src/ast_selectors.hpp +311 -367
  21. data/ext/libsass/src/ast_supports.cpp +1 -17
  22. data/ext/libsass/src/ast_values.cpp +216 -29
  23. data/ext/libsass/src/ast_values.hpp +42 -33
  24. data/ext/libsass/src/bind.cpp +1 -1
  25. data/ext/libsass/src/cencode.c +4 -6
  26. data/ext/libsass/src/check_nesting.cpp +5 -6
  27. data/ext/libsass/src/check_nesting.hpp +4 -0
  28. data/ext/libsass/src/color_maps.cpp +11 -10
  29. data/ext/libsass/src/color_maps.hpp +0 -8
  30. data/ext/libsass/src/constants.cpp +5 -0
  31. data/ext/libsass/src/constants.hpp +6 -0
  32. data/ext/libsass/src/context.cpp +30 -60
  33. data/ext/libsass/src/context.hpp +8 -20
  34. data/ext/libsass/src/cssize.cpp +36 -120
  35. data/ext/libsass/src/cssize.hpp +4 -10
  36. data/ext/libsass/src/dart_helpers.hpp +199 -0
  37. data/ext/libsass/src/debugger.hpp +364 -207
  38. data/ext/libsass/src/emitter.cpp +3 -4
  39. data/ext/libsass/src/emitter.hpp +0 -2
  40. data/ext/libsass/src/environment.hpp +5 -0
  41. data/ext/libsass/src/error_handling.cpp +21 -0
  42. data/ext/libsass/src/error_handling.hpp +25 -3
  43. data/ext/libsass/src/eval.cpp +33 -153
  44. data/ext/libsass/src/eval.hpp +11 -13
  45. data/ext/libsass/src/eval_selectors.cpp +75 -0
  46. data/ext/libsass/src/expand.cpp +214 -167
  47. data/ext/libsass/src/expand.hpp +26 -6
  48. data/ext/libsass/src/extender.cpp +1186 -0
  49. data/ext/libsass/src/extender.hpp +399 -0
  50. data/ext/libsass/src/extension.cpp +43 -0
  51. data/ext/libsass/src/extension.hpp +89 -0
  52. data/ext/libsass/src/file.cpp +15 -14
  53. data/ext/libsass/src/file.hpp +5 -12
  54. data/ext/libsass/src/fn_colors.cpp +12 -10
  55. data/ext/libsass/src/fn_lists.cpp +12 -11
  56. data/ext/libsass/src/fn_miscs.cpp +22 -34
  57. data/ext/libsass/src/fn_numbers.cpp +13 -6
  58. data/ext/libsass/src/fn_selectors.cpp +94 -124
  59. data/ext/libsass/src/fn_strings.cpp +16 -14
  60. data/ext/libsass/src/fn_utils.cpp +5 -6
  61. data/ext/libsass/src/fn_utils.hpp +9 -3
  62. data/ext/libsass/src/inspect.cpp +154 -117
  63. data/ext/libsass/src/inspect.hpp +10 -8
  64. data/ext/libsass/src/lexer.cpp +17 -81
  65. data/ext/libsass/src/lexer.hpp +5 -16
  66. data/ext/libsass/src/listize.cpp +22 -36
  67. data/ext/libsass/src/listize.hpp +8 -9
  68. data/ext/libsass/src/memory/SharedPtr.hpp +39 -5
  69. data/ext/libsass/src/operation.hpp +27 -17
  70. data/ext/libsass/src/operators.cpp +1 -0
  71. data/ext/libsass/src/ordered_map.hpp +112 -0
  72. data/ext/libsass/src/output.cpp +30 -49
  73. data/ext/libsass/src/output.hpp +1 -1
  74. data/ext/libsass/src/parser.cpp +211 -381
  75. data/ext/libsass/src/parser.hpp +17 -15
  76. data/ext/libsass/src/parser_selectors.cpp +189 -0
  77. data/ext/libsass/src/permutate.hpp +140 -0
  78. data/ext/libsass/src/position.hpp +1 -1
  79. data/ext/libsass/src/prelexer.cpp +6 -6
  80. data/ext/libsass/src/remove_placeholders.cpp +55 -56
  81. data/ext/libsass/src/remove_placeholders.hpp +21 -18
  82. data/ext/libsass/src/sass.hpp +1 -0
  83. data/ext/libsass/src/sass2scss.cpp +4 -4
  84. data/ext/libsass/src/sass_context.cpp +42 -91
  85. data/ext/libsass/src/sass_context.hpp +2 -2
  86. data/ext/libsass/src/sass_functions.cpp +1 -1
  87. data/ext/libsass/src/sass_values.cpp +0 -1
  88. data/ext/libsass/src/stylesheet.cpp +22 -0
  89. data/ext/libsass/src/stylesheet.hpp +57 -0
  90. data/ext/libsass/src/to_value.cpp +2 -2
  91. data/ext/libsass/src/to_value.hpp +1 -1
  92. data/ext/libsass/src/units.cpp +5 -3
  93. data/ext/libsass/src/util.cpp +10 -12
  94. data/ext/libsass/src/util.hpp +2 -3
  95. data/ext/libsass/src/util_string.cpp +111 -61
  96. data/ext/libsass/src/util_string.hpp +61 -8
  97. data/lib/sassc/engine.rb +5 -3
  98. data/lib/sassc/functions_handler.rb +8 -8
  99. data/lib/sassc/native.rb +1 -1
  100. data/lib/sassc/script.rb +4 -4
  101. data/lib/sassc/version.rb +1 -1
  102. data/test/functions_test.rb +18 -1
  103. data/test/native_test.rb +1 -1
  104. metadata +17 -12
  105. data/ext/libsass/src/extend.cpp +0 -2132
  106. data/ext/libsass/src/extend.hpp +0 -86
  107. data/ext/libsass/src/node.cpp +0 -322
  108. data/ext/libsass/src/node.hpp +0 -118
  109. data/ext/libsass/src/paths.hpp +0 -71
  110. data/ext/libsass/src/sass_util.cpp +0 -152
  111. data/ext/libsass/src/sass_util.hpp +0 -256
  112. data/ext/libsass/src/subset_map.cpp +0 -58
  113. data/ext/libsass/src/subset_map.hpp +0 -76
@@ -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,531 +21,322 @@ 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
85
- {
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;
90
- throw std::runtime_error("invalid selector base classes to compare");
91
- }
92
-
93
- bool Compound_Selector::operator< (const Selector& rhs) const
24
+ bool SelectorList::operator== (const Selector& rhs) const
94
25
  {
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;
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; }
99
31
  throw std::runtime_error("invalid selector base classes to compare");
100
32
  }
101
33
 
102
- bool Selector_Schema::operator== (const Selector& rhs) const
34
+ bool ComplexSelector::operator== (const Selector& rhs) const
103
35
  {
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;
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; }
108
40
  throw std::runtime_error("invalid selector base classes to compare");
109
41
  }
110
42
 
111
- bool Selector_Schema::operator< (const Selector& rhs) const
43
+ bool SelectorCombinator::operator== (const Selector& rhs) const
112
44
  {
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
153
- {
154
- if (&rhs == this) return true;
155
- if (rhs.length() != length()) return false;
156
- std::unordered_set<const Complex_Selector *, HashPtr, ComparePtrs> lhs_set;
157
- lhs_set.reserve(length());
158
- for (const Complex_Selector_Obj &element : elements()) {
159
- lhs_set.insert(element.ptr());
160
- }
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
70
+ bool SelectorList::operator== (const SelectorList& rhs) const
185
71
  {
186
72
  if (&rhs == this) return true;
187
73
  if (rhs.length() != length()) return false;
188
- std::unordered_set<const Simple_Selector *, HashPtr, ComparePtrs> lhs_set;
74
+ std::unordered_set<const ComplexSelector*, PtrObjHash, PtrObjEquality> lhs_set;
189
75
  lhs_set.reserve(length());
190
- for (const Simple_Selector_Obj &element : elements()) {
76
+ for (const ComplexSelectorObj& element : elements()) {
191
77
  lhs_set.insert(element.ptr());
192
78
  }
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;
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;
371
134
  }
372
135
 
373
- /***************************************************************************/
374
- /***************************************************************************/
136
+ /*#########################################################################*/
137
+ // Compare ComplexSelector against all other selector types
138
+ /*#########################################################################*/
375
139
 
376
- bool Complex_Selector::operator== (const Selector_List& rhs) const
140
+ bool ComplexSelector::operator== (const SelectorList& rhs) const
377
141
  {
378
- size_t len = rhs.length();
379
- if (len > 1) return false;
380
- if (len == 0) return empty();
381
- return *this == *rhs.at(0);
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);
382
148
  }
383
149
 
384
- bool Complex_Selector::operator< (const Selector_List& rhs) const
150
+ bool ComplexSelector::operator== (const CompoundSelector& rhs) const
385
151
  {
386
- size_t len = rhs.length();
387
- if (len > 1) return true;
388
- if (len == 0) return false;
389
- return *this < *rhs.at(0);
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;
390
158
  }
391
159
 
392
- bool Complex_Selector::operator== (const Compound_Selector& rhs) const
160
+ bool ComplexSelector::operator== (const SimpleSelector& rhs) const
393
161
  {
394
- if (tail()) return false;
395
- if (!head()) return rhs.empty();
396
- 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;
397
168
  }
398
169
 
399
- bool Complex_Selector::operator< (const Compound_Selector& rhs) const
170
+ /*#########################################################################*/
171
+ // Compare SelectorCombinator against itself
172
+ /*#########################################################################*/
173
+
174
+ bool SelectorCombinator::operator==(const SelectorCombinator& rhs) const
400
175
  {
401
- if (tail()) return false;
402
- if (!head()) return !rhs.empty();
403
- return *head() < rhs;
176
+ return combinator() == rhs.combinator();
404
177
  }
405
178
 
406
- bool Complex_Selector::operator== (const Simple_Selector& rhs) const
179
+ /*#########################################################################*/
180
+ // Compare SelectorCombinator against SelectorComponent
181
+ /*#########################################################################*/
182
+
183
+ bool SelectorCombinator::operator==(const SelectorComponent& rhs) const
407
184
  {
408
- if (tail()) return false;
409
- if (!head()) return rhs.empty();
410
- return *head() == rhs;
185
+ if (const SelectorCombinator * sel = rhs.getCombinator()) {
186
+ return *this == *sel;
187
+ }
188
+ return false;
411
189
  }
412
190
 
413
- bool Complex_Selector::operator< (const Simple_Selector& rhs) const
191
+ bool CompoundSelector::operator==(const SelectorComponent& rhs) const
414
192
  {
415
- if (tail()) return false;
416
- if (!head()) return !rhs.empty();
417
- return *head() < rhs;
193
+ if (const CompoundSelector * sel = rhs.getCompound()) {
194
+ return *this == *sel;
195
+ }
196
+ return false;
418
197
  }
419
198
 
420
- /***************************************************************************/
421
- /***************************************************************************/
199
+ /*#########################################################################*/
200
+ // Compare CompoundSelector against itself
201
+ /*#########################################################################*/
202
+ // ToDo: Verifiy implementation
203
+ /*#########################################################################*/
422
204
 
423
- bool Compound_Selector::operator== (const Selector_List& rhs) const
205
+ bool CompoundSelector::operator== (const CompoundSelector& rhs) const
424
206
  {
425
- size_t len = rhs.length();
426
- if (len > 1) return false;
427
- if (len == 0) return empty();
428
- return *this == *rhs.at(0);
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;
429
220
  }
430
221
 
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
- }
438
222
 
439
- bool Compound_Selector::operator== (const Complex_Selector& rhs) const
440
- {
441
- if (rhs.tail()) return false;
442
- if (!rhs.head()) return empty();
443
- return *this == *rhs.head();
444
- }
223
+ /*#########################################################################*/
224
+ // Compare CompoundSelector against all other selector types
225
+ /*#########################################################################*/
445
226
 
446
- bool Compound_Selector::operator< (const Complex_Selector& rhs) const
227
+ bool CompoundSelector::operator== (const SelectorList& rhs) const
447
228
  {
448
- if (rhs.tail()) return true;
449
- if (!rhs.head()) return false;
450
- return *this < *rhs.head();
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);
451
235
  }
452
236
 
453
- bool Compound_Selector::operator< (const Simple_Selector& rhs) const
237
+ bool CompoundSelector::operator== (const ComplexSelector& rhs) const
454
238
  {
455
- size_t len = length();
456
- if (len > 1) return false;
457
- if (len == 0) return rhs.empty();
458
- return *at(0) == rhs;
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);
459
245
  }
460
246
 
461
- bool Compound_Selector::operator== (const Simple_Selector& rhs) const
247
+ bool CompoundSelector::operator== (const SimpleSelector& rhs) const
462
248
  {
463
- size_t len = length();
464
- if (len > 1) return false;
465
- if (len == 0) return !rhs.empty();
466
- return *at(0) < rhs;
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;
467
257
  }
468
258
 
469
- /***************************************************************************/
470
- /***************************************************************************/
471
-
472
- bool Simple_Selector::operator== (const Selector_List& rhs) const
473
- {
474
- return rhs.length() == 1 && *this == *rhs.at(0);
475
- }
259
+ /*#########################################################################*/
260
+ // Compare SimpleSelector against itself (upcast from abstract base)
261
+ /*#########################################################################*/
476
262
 
477
- bool Simple_Selector::operator< (const Selector_List& rhs) const
478
- {
479
- size_t len = rhs.length();
480
- if (len > 1) return true;
481
- if (len == 0) return false;
482
- return *this < *rhs.at(0);
483
- }
263
+ // DOES NOT EXIST FOR ABSTRACT BASE CLASS
484
264
 
485
- bool Simple_Selector::operator== (const Complex_Selector& rhs) const
486
- {
487
- return !rhs.tail() && rhs.head() &&
488
- rhs.combinator() == Complex_Selector::ANCESTOR_OF &&
489
- *this == *rhs.head();
490
- }
265
+ /*#########################################################################*/
266
+ // Compare SimpleSelector against all other selector types
267
+ /*#########################################################################*/
491
268
 
492
- bool Simple_Selector::operator< (const Complex_Selector& rhs) const
269
+ bool SimpleSelector::operator== (const SelectorList& rhs) const
493
270
  {
494
- if (rhs.tail()) return true;
495
- if (!rhs.head()) return false;
496
- return *this < *rhs.head();
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);
497
277
  }
498
278
 
499
- bool Simple_Selector::operator== (const Compound_Selector& rhs) const
279
+ bool SimpleSelector::operator== (const ComplexSelector& rhs) const
500
280
  {
501
- return rhs.length() == 1 && *this == *rhs.at(0);
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);
502
287
  }
503
288
 
504
- bool Simple_Selector::operator< (const Compound_Selector& rhs) const
289
+ bool SimpleSelector::operator== (const CompoundSelector& rhs) const
505
290
  {
506
- size_t len = rhs.length();
507
- if (len > 1) return true;
508
- if (len == 0) return false;
509
- return *this < *rhs.at(0);
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);
510
297
  }
511
298
 
512
299
  /*#########################################################################*/
513
300
  /*#########################################################################*/
514
301
 
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;
528
- }
529
-
530
- /***************************************************************************/
531
- /***************************************************************************/
532
-
533
- bool Id_Selector::operator== (const Simple_Selector& rhs) const
302
+ bool Id_Selector::operator== (const SimpleSelector& rhs) const
534
303
  {
535
304
  auto sel = Cast<Id_Selector>(&rhs);
536
305
  return sel ? *this == *sel : false;
537
306
  }
538
307
 
539
- bool Type_Selector::operator== (const Simple_Selector& rhs) const
308
+ bool Type_Selector::operator== (const SimpleSelector& rhs) const
540
309
  {
541
310
  auto sel = Cast<Type_Selector>(&rhs);
542
311
  return sel ? *this == *sel : false;
543
312
  }
544
313
 
545
- bool Class_Selector::operator== (const Simple_Selector& rhs) const
314
+ bool Class_Selector::operator== (const SimpleSelector& rhs) const
546
315
  {
547
316
  auto sel = Cast<Class_Selector>(&rhs);
548
317
  return sel ? *this == *sel : false;
549
318
  }
550
319
 
551
- bool Parent_Selector::operator== (const Simple_Selector& rhs) const
552
- {
553
- auto sel = Cast<Parent_Selector>(&rhs);
554
- return sel ? *this == *sel : false;
555
- }
556
-
557
- bool Pseudo_Selector::operator== (const Simple_Selector& rhs) const
320
+ bool Pseudo_Selector::operator== (const SimpleSelector& rhs) const
558
321
  {
559
322
  auto sel = Cast<Pseudo_Selector>(&rhs);
560
323
  return sel ? *this == *sel : false;
561
324
  }
562
325
 
563
- bool Wrapped_Selector::operator== (const Simple_Selector& rhs) const
564
- {
565
- auto sel = Cast<Wrapped_Selector>(&rhs);
566
- return sel ? *this == *sel : false;
567
- }
568
-
569
- bool Attribute_Selector::operator== (const Simple_Selector& rhs) const
326
+ bool Attribute_Selector::operator== (const SimpleSelector& rhs) const
570
327
  {
571
328
  auto sel = Cast<Attribute_Selector>(&rhs);
572
329
  return sel ? *this == *sel : false;
573
330
  }
574
331
 
575
- bool Placeholder_Selector::operator== (const Simple_Selector& rhs) const
332
+ bool Placeholder_Selector::operator== (const SimpleSelector& rhs) const
576
333
  {
577
334
  auto sel = Cast<Placeholder_Selector>(&rhs);
578
335
  return sel ? *this == *sel : false;
579
336
  }
580
337
 
581
- /***************************************************************************/
582
- /***************************************************************************/
338
+ /*#########################################################################*/
339
+ /*#########################################################################*/
583
340
 
584
341
  bool Id_Selector::operator== (const Id_Selector& rhs) const
585
342
  {
@@ -598,309 +355,39 @@ namespace Sass {
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
358
  bool Placeholder_Selector::operator== (const Placeholder_Selector& 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
841
- {
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
364
+ bool Attribute_Selector::operator== (const Attribute_Selector& rhs) const
853
365
  {
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 Pseudo_Selector::operator== (const Pseudo_Selector& 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
  /*#########################################################################*/