sassc 2.2.1 → 2.3.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 (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
  /*#########################################################################*/