sassc 2.0.1 → 2.1.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (200) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.gitmodules +1 -1
  4. data/.travis.yml +7 -3
  5. data/CHANGELOG.md +3 -0
  6. data/CODE_OF_CONDUCT.md +1 -1
  7. data/README.md +1 -1
  8. data/Rakefile +23 -8
  9. data/ext/extconf.rb +39 -0
  10. data/ext/libsass/.gitignore +1 -0
  11. data/ext/libsass/GNUmakefile.am +23 -39
  12. data/ext/libsass/Makefile +56 -91
  13. data/ext/libsass/Makefile.conf +16 -2
  14. data/ext/libsass/configure.ac +8 -12
  15. data/ext/libsass/include/sass/base.h +1 -0
  16. data/ext/libsass/include/sass/context.h +1 -1
  17. data/ext/libsass/src/GNUmakefile.am +1 -5
  18. data/ext/libsass/src/ast.cpp +747 -2010
  19. data/ext/libsass/src/ast.hpp +239 -2383
  20. data/ext/libsass/src/{to_c.cpp → ast2c.cpp} +22 -16
  21. data/ext/libsass/src/ast2c.hpp +39 -0
  22. data/ext/libsass/src/ast_def_macros.hpp +62 -10
  23. data/ext/libsass/src/ast_fwd_decl.cpp +1 -0
  24. data/ext/libsass/src/ast_fwd_decl.hpp +43 -165
  25. data/ext/libsass/src/ast_sel_cmp.cpp +909 -0
  26. data/ext/libsass/src/ast_sel_unify.cpp +280 -0
  27. data/ext/libsass/src/ast_selectors.cpp +1475 -0
  28. data/ext/libsass/src/ast_selectors.hpp +568 -0
  29. data/ext/libsass/src/ast_supports.cpp +130 -0
  30. data/ext/libsass/src/ast_supports.hpp +121 -0
  31. data/ext/libsass/src/ast_values.cpp +967 -0
  32. data/ext/libsass/src/ast_values.hpp +489 -0
  33. data/ext/libsass/src/backtrace.cpp +4 -0
  34. data/ext/libsass/src/base64vlq.cpp +3 -0
  35. data/ext/libsass/src/bind.cpp +18 -17
  36. data/ext/libsass/src/bind.hpp +3 -1
  37. data/ext/libsass/src/c2ast.cpp +64 -0
  38. data/ext/libsass/src/c2ast.hpp +14 -0
  39. data/ext/libsass/src/cencode.c +2 -2
  40. data/ext/libsass/src/check_nesting.cpp +52 -56
  41. data/ext/libsass/src/check_nesting.hpp +35 -34
  42. data/ext/libsass/src/color_maps.cpp +156 -153
  43. data/ext/libsass/src/color_maps.hpp +152 -152
  44. data/ext/libsass/src/constants.cpp +15 -0
  45. data/ext/libsass/src/constants.hpp +13 -0
  46. data/ext/libsass/src/context.cpp +24 -14
  47. data/ext/libsass/src/context.hpp +6 -6
  48. data/ext/libsass/src/cssize.cpp +69 -71
  49. data/ext/libsass/src/cssize.hpp +50 -50
  50. data/ext/libsass/src/debugger.hpp +117 -110
  51. data/ext/libsass/src/emitter.cpp +13 -12
  52. data/ext/libsass/src/emitter.hpp +13 -9
  53. data/ext/libsass/src/environment.cpp +15 -1
  54. data/ext/libsass/src/environment.hpp +6 -0
  55. data/ext/libsass/src/error_handling.cpp +36 -59
  56. data/ext/libsass/src/error_handling.hpp +29 -16
  57. data/ext/libsass/src/eval.cpp +302 -323
  58. data/ext/libsass/src/eval.hpp +64 -55
  59. data/ext/libsass/src/expand.cpp +94 -88
  60. data/ext/libsass/src/expand.hpp +33 -37
  61. data/ext/libsass/src/extend.cpp +38 -36
  62. data/ext/libsass/src/extend.hpp +15 -15
  63. data/ext/libsass/src/file.cpp +34 -2
  64. data/ext/libsass/src/fn_colors.cpp +594 -0
  65. data/ext/libsass/src/fn_colors.hpp +85 -0
  66. data/ext/libsass/src/fn_lists.cpp +284 -0
  67. data/ext/libsass/src/fn_lists.hpp +34 -0
  68. data/ext/libsass/src/fn_maps.cpp +94 -0
  69. data/ext/libsass/src/fn_maps.hpp +30 -0
  70. data/ext/libsass/src/fn_miscs.cpp +256 -0
  71. data/ext/libsass/src/fn_miscs.hpp +40 -0
  72. data/ext/libsass/src/fn_numbers.cpp +220 -0
  73. data/ext/libsass/src/fn_numbers.hpp +45 -0
  74. data/ext/libsass/src/fn_selectors.cpp +235 -0
  75. data/ext/libsass/src/fn_selectors.hpp +35 -0
  76. data/ext/libsass/src/fn_strings.cpp +254 -0
  77. data/ext/libsass/src/fn_strings.hpp +34 -0
  78. data/ext/libsass/src/fn_utils.cpp +156 -0
  79. data/ext/libsass/src/fn_utils.hpp +56 -0
  80. data/ext/libsass/src/inspect.cpp +101 -152
  81. data/ext/libsass/src/inspect.hpp +69 -73
  82. data/ext/libsass/src/json.cpp +2 -2
  83. data/ext/libsass/src/lexer.cpp +6 -3
  84. data/ext/libsass/src/listize.cpp +9 -11
  85. data/ext/libsass/src/listize.hpp +11 -7
  86. data/ext/libsass/src/memory/SharedPtr.cpp +2 -83
  87. data/ext/libsass/src/memory/SharedPtr.hpp +127 -143
  88. data/ext/libsass/src/node.cpp +13 -10
  89. data/ext/libsass/src/node.hpp +3 -3
  90. data/ext/libsass/src/operation.hpp +184 -144
  91. data/ext/libsass/src/operators.cpp +43 -17
  92. data/ext/libsass/src/operators.hpp +5 -5
  93. data/ext/libsass/src/output.cpp +21 -18
  94. data/ext/libsass/src/output.hpp +14 -21
  95. data/ext/libsass/src/parser.cpp +215 -183
  96. data/ext/libsass/src/parser.hpp +28 -24
  97. data/ext/libsass/src/plugins.cpp +5 -1
  98. data/ext/libsass/src/position.cpp +3 -0
  99. data/ext/libsass/src/prelexer.cpp +9 -3
  100. data/ext/libsass/src/prelexer.hpp +9 -9
  101. data/ext/libsass/src/remove_placeholders.cpp +14 -11
  102. data/ext/libsass/src/remove_placeholders.hpp +8 -9
  103. data/ext/libsass/src/sass.cpp +9 -3
  104. data/ext/libsass/src/sass.hpp +12 -9
  105. data/ext/libsass/src/sass2scss.cpp +45 -14
  106. data/ext/libsass/src/sass_context.cpp +18 -15
  107. data/ext/libsass/src/sass_functions.cpp +6 -3
  108. data/ext/libsass/src/sass_functions.hpp +1 -1
  109. data/ext/libsass/src/sass_util.cpp +3 -0
  110. data/ext/libsass/src/sass_values.cpp +21 -13
  111. data/ext/libsass/src/source_map.cpp +5 -2
  112. data/ext/libsass/src/source_map.hpp +2 -2
  113. data/ext/libsass/src/subset_map.cpp +4 -1
  114. data/ext/libsass/src/to_value.cpp +23 -21
  115. data/ext/libsass/src/to_value.hpp +18 -22
  116. data/ext/libsass/src/units.cpp +4 -0
  117. data/ext/libsass/src/units.hpp +1 -0
  118. data/ext/libsass/src/utf8/checked.h +12 -10
  119. data/ext/libsass/src/utf8/core.h +3 -0
  120. data/ext/libsass/src/utf8_string.cpp +3 -0
  121. data/ext/libsass/src/util.cpp +67 -75
  122. data/ext/libsass/src/util.hpp +64 -19
  123. data/ext/libsass/src/util_string.cpp +75 -0
  124. data/ext/libsass/src/util_string.hpp +19 -0
  125. data/ext/libsass/src/values.cpp +22 -13
  126. data/ext/libsass/src/values.hpp +2 -2
  127. data/ext/libsass/win/libsass.targets +30 -4
  128. data/ext/libsass/win/libsass.vcxproj.filters +82 -4
  129. data/lib/sassc.rb +24 -0
  130. data/lib/sassc/engine.rb +2 -2
  131. data/lib/sassc/native.rb +8 -1
  132. data/lib/sassc/version.rb +1 -1
  133. data/sassc.gemspec +19 -11
  134. data/test/engine_test.rb +26 -1
  135. data/test/native_test.rb +1 -1
  136. metadata +66 -72
  137. data/ext/Rakefile +0 -3
  138. data/ext/libsass/.github/CONTRIBUTING.md +0 -65
  139. data/ext/libsass/.github/ISSUE_TEMPLATE.md +0 -54
  140. data/ext/libsass/.travis.yml +0 -64
  141. data/ext/libsass/Readme.md +0 -104
  142. data/ext/libsass/SECURITY.md +0 -10
  143. data/ext/libsass/appveyor.yml +0 -91
  144. data/ext/libsass/docs/README.md +0 -20
  145. data/ext/libsass/docs/api-context-example.md +0 -45
  146. data/ext/libsass/docs/api-context-internal.md +0 -163
  147. data/ext/libsass/docs/api-context.md +0 -295
  148. data/ext/libsass/docs/api-doc.md +0 -215
  149. data/ext/libsass/docs/api-function-example.md +0 -67
  150. data/ext/libsass/docs/api-function-internal.md +0 -8
  151. data/ext/libsass/docs/api-function.md +0 -74
  152. data/ext/libsass/docs/api-importer-example.md +0 -112
  153. data/ext/libsass/docs/api-importer-internal.md +0 -20
  154. data/ext/libsass/docs/api-importer.md +0 -86
  155. data/ext/libsass/docs/api-value-example.md +0 -55
  156. data/ext/libsass/docs/api-value-internal.md +0 -76
  157. data/ext/libsass/docs/api-value.md +0 -154
  158. data/ext/libsass/docs/build-on-darwin.md +0 -27
  159. data/ext/libsass/docs/build-on-gentoo.md +0 -55
  160. data/ext/libsass/docs/build-on-windows.md +0 -139
  161. data/ext/libsass/docs/build-shared-library.md +0 -35
  162. data/ext/libsass/docs/build-with-autotools.md +0 -78
  163. data/ext/libsass/docs/build-with-makefiles.md +0 -68
  164. data/ext/libsass/docs/build-with-mingw.md +0 -107
  165. data/ext/libsass/docs/build-with-visual-studio.md +0 -90
  166. data/ext/libsass/docs/build.md +0 -97
  167. data/ext/libsass/docs/compatibility-plan.md +0 -48
  168. data/ext/libsass/docs/contributing.md +0 -17
  169. data/ext/libsass/docs/custom-functions-internal.md +0 -122
  170. data/ext/libsass/docs/dev-ast-memory.md +0 -223
  171. data/ext/libsass/docs/implementations.md +0 -56
  172. data/ext/libsass/docs/plugins.md +0 -47
  173. data/ext/libsass/docs/setup-environment.md +0 -68
  174. data/ext/libsass/docs/source-map-internals.md +0 -51
  175. data/ext/libsass/docs/trace.md +0 -26
  176. data/ext/libsass/docs/triage.md +0 -17
  177. data/ext/libsass/docs/unicode.md +0 -39
  178. data/ext/libsass/extconf.rb +0 -6
  179. data/ext/libsass/script/bootstrap +0 -13
  180. data/ext/libsass/script/branding +0 -10
  181. data/ext/libsass/script/ci-build-libsass +0 -134
  182. data/ext/libsass/script/ci-build-plugin +0 -62
  183. data/ext/libsass/script/ci-install-compiler +0 -6
  184. data/ext/libsass/script/ci-install-deps +0 -20
  185. data/ext/libsass/script/ci-report-coverage +0 -42
  186. data/ext/libsass/script/spec +0 -5
  187. data/ext/libsass/script/tap-driver +0 -652
  188. data/ext/libsass/script/tap-runner +0 -1
  189. data/ext/libsass/script/test-leaks.pl +0 -103
  190. data/ext/libsass/src/functions.cpp +0 -2234
  191. data/ext/libsass/src/functions.hpp +0 -198
  192. data/ext/libsass/src/to_c.hpp +0 -39
  193. data/ext/libsass/test/test_node.cpp +0 -94
  194. data/ext/libsass/test/test_paths.cpp +0 -28
  195. data/ext/libsass/test/test_selector_difference.cpp +0 -25
  196. data/ext/libsass/test/test_specificity.cpp +0 -25
  197. data/ext/libsass/test/test_subset_map.cpp +0 -472
  198. data/ext/libsass/test/test_superselector.cpp +0 -69
  199. data/ext/libsass/test/test_unification.cpp +0 -31
  200. data/lib/tasks/libsass.rb +0 -33
@@ -0,0 +1,909 @@
1
+ // sass.hpp must go before all system headers to get the
2
+ // __EXTENSIONS__ fix on Solaris.
3
+ #include "sass.hpp"
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
+ #include "ast_selectors.hpp"
22
+
23
+ namespace Sass {
24
+
25
+ /*#########################################################################*/
26
+ /*#########################################################################*/
27
+
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
+ // Selector lists can be compared to comma lists
49
+ bool Selector_List::operator== (const Expression& rhs) const
50
+ {
51
+ if (auto l = Cast<List>(&rhs)) { return *this == *l; }
52
+ if (auto s = Cast<Selector>(&rhs)) { return *this == *s; }
53
+ if (Cast<String>(&rhs) || Cast<Null>(&rhs)) { return false; }
54
+ throw std::runtime_error("invalid selector base classes to compare");
55
+ }
56
+
57
+ // 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
94
+ {
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;
99
+ throw std::runtime_error("invalid selector base classes to compare");
100
+ }
101
+
102
+ bool Selector_Schema::operator== (const Selector& rhs) const
103
+ {
104
+ if (auto sl = Cast<Selector_List>(&rhs)) return *this == *sl;
105
+ if (auto ss = Cast<Simple_Selector>(&rhs)) return *this == *ss;
106
+ if (auto cs = Cast<Complex_Selector>(&rhs)) return *this == *cs;
107
+ if (auto ch = Cast<Compound_Selector>(&rhs)) return *this == *ch;
108
+ throw std::runtime_error("invalid selector base classes to compare");
109
+ }
110
+
111
+ bool Selector_Schema::operator< (const Selector& rhs) const
112
+ {
113
+ if (auto sl = Cast<Selector_List>(&rhs)) return *this < *sl;
114
+ if (auto ss = Cast<Simple_Selector>(&rhs)) return *this < *ss;
115
+ if (auto cs = Cast<Complex_Selector>(&rhs)) return *this < *cs;
116
+ if (auto ch = Cast<Compound_Selector>(&rhs)) return *this < *ch;
117
+ throw std::runtime_error("invalid selector base classes to compare");
118
+ }
119
+
120
+ bool Simple_Selector::operator== (const Selector& rhs) const
121
+ {
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;
126
+ throw std::runtime_error("invalid selector base classes to compare");
127
+ }
128
+
129
+ bool Simple_Selector::operator< (const Selector& rhs) const
130
+ {
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;
135
+ throw std::runtime_error("invalid selector base classes to compare");
136
+ }
137
+
138
+ /*#########################################################################*/
139
+ /*#########################################################################*/
140
+
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
185
+ {
186
+ if (&rhs == this) return true;
187
+ if (rhs.length() != length()) return false;
188
+ std::unordered_set<const Simple_Selector *, HashPtr, ComparePtrs> lhs_set;
189
+ lhs_set.reserve(length());
190
+ for (const Simple_Selector_Obj &element : elements()) {
191
+ lhs_set.insert(element.ptr());
192
+ }
193
+ // there is no break?!
194
+ for (const Simple_Selector_Obj &element : rhs.elements()) {
195
+ if (lhs_set.find(element.ptr()) == lhs_set.end()) return false;
196
+ }
197
+ return true;
198
+ }
199
+
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
+
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
+
322
+ /*#########################################################################*/
323
+ /*#########################################################################*/
324
+
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
334
+ {
335
+ size_t len = length();
336
+ if (len > 1) return false;
337
+ if (len == 0) return !rhs.empty();
338
+ return *at(0) < rhs;
339
+ }
340
+
341
+ bool Selector_List::operator== (const Compound_Selector& rhs) const
342
+ {
343
+ size_t len = length();
344
+ if (len > 1) return false;
345
+ if (len == 0) return rhs.empty();
346
+ return *at(0) == rhs;
347
+ }
348
+
349
+ bool Selector_List::operator< (const Compound_Selector& rhs) const
350
+ {
351
+ size_t len = length();
352
+ if (len > 1) return false;
353
+ if (len == 0) return !rhs.empty();
354
+ return *at(0) < rhs;
355
+ }
356
+
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
+ }
364
+
365
+ bool Selector_List::operator< (const Simple_Selector& rhs) const
366
+ {
367
+ size_t len = length();
368
+ if (len > 1) return false;
369
+ if (len == 0) return !rhs.empty();
370
+ return *at(0) < rhs;
371
+ }
372
+
373
+ /***************************************************************************/
374
+ /***************************************************************************/
375
+
376
+ bool Complex_Selector::operator== (const Selector_List& rhs) const
377
+ {
378
+ size_t len = rhs.length();
379
+ if (len > 1) return false;
380
+ if (len == 0) return empty();
381
+ return *this == *rhs.at(0);
382
+ }
383
+
384
+ bool Complex_Selector::operator< (const Selector_List& rhs) const
385
+ {
386
+ size_t len = rhs.length();
387
+ if (len > 1) return true;
388
+ if (len == 0) return false;
389
+ return *this < *rhs.at(0);
390
+ }
391
+
392
+ bool Complex_Selector::operator== (const Compound_Selector& rhs) const
393
+ {
394
+ if (tail()) return false;
395
+ if (!head()) return rhs.empty();
396
+ return *head() == rhs;
397
+ }
398
+
399
+ bool Complex_Selector::operator< (const Compound_Selector& rhs) const
400
+ {
401
+ if (tail()) return false;
402
+ if (!head()) return !rhs.empty();
403
+ return *head() < rhs;
404
+ }
405
+
406
+ bool Complex_Selector::operator== (const Simple_Selector& rhs) const
407
+ {
408
+ if (tail()) return false;
409
+ if (!head()) return rhs.empty();
410
+ return *head() == rhs;
411
+ }
412
+
413
+ bool Complex_Selector::operator< (const Simple_Selector& rhs) const
414
+ {
415
+ if (tail()) return false;
416
+ if (!head()) return !rhs.empty();
417
+ return *head() < rhs;
418
+ }
419
+
420
+ /***************************************************************************/
421
+ /***************************************************************************/
422
+
423
+ bool Compound_Selector::operator== (const Selector_List& rhs) const
424
+ {
425
+ size_t len = rhs.length();
426
+ if (len > 1) return false;
427
+ if (len == 0) return empty();
428
+ return *this == *rhs.at(0);
429
+ }
430
+
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
+
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
+ }
445
+
446
+ bool Compound_Selector::operator< (const Complex_Selector& rhs) const
447
+ {
448
+ if (rhs.tail()) return true;
449
+ if (!rhs.head()) return false;
450
+ return *this < *rhs.head();
451
+ }
452
+
453
+ bool Compound_Selector::operator< (const Simple_Selector& rhs) const
454
+ {
455
+ size_t len = length();
456
+ if (len > 1) return false;
457
+ if (len == 0) return rhs.empty();
458
+ return *at(0) == rhs;
459
+ }
460
+
461
+ bool Compound_Selector::operator== (const Simple_Selector& rhs) const
462
+ {
463
+ size_t len = length();
464
+ if (len > 1) return false;
465
+ if (len == 0) return !rhs.empty();
466
+ return *at(0) < rhs;
467
+ }
468
+
469
+ /***************************************************************************/
470
+ /***************************************************************************/
471
+
472
+ bool Simple_Selector::operator== (const Selector_List& rhs) const
473
+ {
474
+ return rhs.length() == 1 && *this == *rhs.at(0);
475
+ }
476
+
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
+ }
484
+
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
+ }
491
+
492
+ bool Simple_Selector::operator< (const Complex_Selector& rhs) const
493
+ {
494
+ if (rhs.tail()) return true;
495
+ if (!rhs.head()) return false;
496
+ return *this < *rhs.head();
497
+ }
498
+
499
+ bool Simple_Selector::operator== (const Compound_Selector& rhs) const
500
+ {
501
+ return rhs.length() == 1 && *this == *rhs.at(0);
502
+ }
503
+
504
+ bool Simple_Selector::operator< (const Compound_Selector& rhs) const
505
+ {
506
+ size_t len = rhs.length();
507
+ if (len > 1) return true;
508
+ if (len == 0) return false;
509
+ return *this < *rhs.at(0);
510
+ }
511
+
512
+ /*#########################################################################*/
513
+ /*#########################################################################*/
514
+
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
534
+ {
535
+ auto sel = Cast<Id_Selector>(&rhs);
536
+ return sel ? *this == *sel : false;
537
+ }
538
+
539
+ bool Type_Selector::operator== (const Simple_Selector& rhs) const
540
+ {
541
+ auto sel = Cast<Type_Selector>(&rhs);
542
+ return sel ? *this == *sel : false;
543
+ }
544
+
545
+ bool Class_Selector::operator== (const Simple_Selector& rhs) const
546
+ {
547
+ auto sel = Cast<Class_Selector>(&rhs);
548
+ return sel ? *this == *sel : false;
549
+ }
550
+
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
558
+ {
559
+ auto sel = Cast<Pseudo_Selector>(&rhs);
560
+ return sel ? *this == *sel : false;
561
+ }
562
+
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
570
+ {
571
+ auto sel = Cast<Attribute_Selector>(&rhs);
572
+ return sel ? *this == *sel : false;
573
+ }
574
+
575
+ bool Placeholder_Selector::operator== (const Simple_Selector& rhs) const
576
+ {
577
+ auto sel = Cast<Placeholder_Selector>(&rhs);
578
+ return sel ? *this == *sel : false;
579
+ }
580
+
581
+ /***************************************************************************/
582
+ /***************************************************************************/
583
+
584
+ bool Id_Selector::operator== (const Id_Selector& rhs) const
585
+ {
586
+ // ID has no namespacing
587
+ return name() == rhs.name();
588
+ }
589
+
590
+ bool Type_Selector::operator== (const Type_Selector& rhs) const
591
+ {
592
+ return is_ns_eq(rhs) && name() == rhs.name();
593
+ }
594
+
595
+ bool Class_Selector::operator== (const Class_Selector& rhs) const
596
+ {
597
+ // Class has no namespacing
598
+ return name() == rhs.name();
599
+ }
600
+
601
+ bool Parent_Selector::operator== (const Parent_Selector& rhs) const
602
+ {
603
+ // Parent has no namespacing
604
+ return name() == rhs.name();
605
+ }
606
+
607
+ bool Pseudo_Selector::operator== (const Pseudo_Selector& rhs) const
608
+ {
609
+ std::string lname = name();
610
+ std::string rname = rhs.name();
611
+ if (is_pseudo_class_element(lname)) {
612
+ if (rname[0] == ':' && rname[1] == ':') {
613
+ lname = lname.substr(1, std::string::npos);
614
+ }
615
+ }
616
+ // right hand is special pseudo (single colon)
617
+ if (is_pseudo_class_element(rname)) {
618
+ if (lname[0] == ':' && lname[1] == ':') {
619
+ lname = lname.substr(1, std::string::npos);
620
+ }
621
+ }
622
+ // Pseudo has no namespacing
623
+ if (lname != rname) return false;
624
+ String_Obj lhs_ex = expression();
625
+ String_Obj rhs_ex = rhs.expression();
626
+ if (rhs_ex && lhs_ex) return *lhs_ex == *rhs_ex;
627
+ else return lhs_ex.ptr() == rhs_ex.ptr();
628
+ }
629
+
630
+ bool Wrapped_Selector::operator== (const Wrapped_Selector& rhs) const
631
+ {
632
+ // Wrapped has no namespacing
633
+ if (name() != rhs.name()) return false;
634
+ return *(selector()) == *(rhs.selector());
635
+ }
636
+
637
+ bool Attribute_Selector::operator== (const Attribute_Selector& rhs) const
638
+ {
639
+ // get optional value state
640
+ bool no_lhs_val = value().isNull();
641
+ bool no_rhs_val = rhs.value().isNull();
642
+ // both are null, therefore equal
643
+ if (no_lhs_val && no_rhs_val) {
644
+ return (name() == rhs.name())
645
+ && (matcher() == rhs.matcher())
646
+ && (is_ns_eq(rhs));
647
+ }
648
+ // both are defined, evaluate
649
+ if (no_lhs_val == no_rhs_val) {
650
+ return (name() == rhs.name())
651
+ && (matcher() == rhs.matcher())
652
+ && (is_ns_eq(rhs))
653
+ && (*value() == *rhs.value());
654
+ }
655
+ // not equal
656
+ return false;
657
+ }
658
+
659
+ bool Placeholder_Selector::operator== (const Placeholder_Selector& rhs) const
660
+ {
661
+ // Placeholder has no namespacing
662
+ return name() == rhs.name();
663
+ }
664
+
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
853
+ {
854
+ std::string lname = name();
855
+ std::string rname = rhs.name();
856
+ if (is_pseudo_class_element(lname)) {
857
+ if (rname[0] == ':' && rname[1] == ':') {
858
+ lname = lname.substr(1, std::string::npos);
859
+ }
860
+ }
861
+ // right hand is special pseudo (single colon)
862
+ if (is_pseudo_class_element(rname)) {
863
+ if (lname[0] == ':' && lname[1] == ':') {
864
+ lname = lname.substr(1, std::string::npos);
865
+ }
866
+ }
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());
882
+ }
883
+
884
+ bool Attribute_Selector::operator< (const Attribute_Selector& rhs) const
885
+ {
886
+ 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();
904
+ }
905
+
906
+ /*#########################################################################*/
907
+ /*#########################################################################*/
908
+
909
+ }