sassc4 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +16 -0
  5. data/CHANGELOG.md +97 -0
  6. data/CODE_OF_CONDUCT.md +10 -0
  7. data/Gemfile +2 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +80 -0
  10. data/Rakefile +51 -0
  11. data/ext/depend +4 -0
  12. data/ext/extconf.rb +92 -0
  13. data/ext/libsass/VERSION +1 -0
  14. data/ext/libsass/contrib/plugin.cpp +60 -0
  15. data/ext/libsass/include/sass/base.h +97 -0
  16. data/ext/libsass/include/sass/context.h +174 -0
  17. data/ext/libsass/include/sass/functions.h +139 -0
  18. data/ext/libsass/include/sass/values.h +145 -0
  19. data/ext/libsass/include/sass/version.h +12 -0
  20. data/ext/libsass/include/sass.h +15 -0
  21. data/ext/libsass/include/sass2scss.h +120 -0
  22. data/ext/libsass/src/MurmurHash2.hpp +91 -0
  23. data/ext/libsass/src/ast.cpp +953 -0
  24. data/ext/libsass/src/ast.hpp +1064 -0
  25. data/ext/libsass/src/ast2c.cpp +80 -0
  26. data/ext/libsass/src/ast2c.hpp +39 -0
  27. data/ext/libsass/src/ast_def_macros.hpp +140 -0
  28. data/ext/libsass/src/ast_fwd_decl.cpp +31 -0
  29. data/ext/libsass/src/ast_fwd_decl.hpp +274 -0
  30. data/ext/libsass/src/ast_helpers.hpp +316 -0
  31. data/ext/libsass/src/ast_sel_cmp.cpp +396 -0
  32. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  33. data/ext/libsass/src/ast_sel_unify.cpp +275 -0
  34. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  35. data/ext/libsass/src/ast_selectors.cpp +1070 -0
  36. data/ext/libsass/src/ast_selectors.hpp +523 -0
  37. data/ext/libsass/src/ast_supports.cpp +114 -0
  38. data/ext/libsass/src/ast_supports.hpp +121 -0
  39. data/ext/libsass/src/ast_values.cpp +1154 -0
  40. data/ext/libsass/src/ast_values.hpp +498 -0
  41. data/ext/libsass/src/b64/cencode.h +32 -0
  42. data/ext/libsass/src/b64/encode.h +79 -0
  43. data/ext/libsass/src/backtrace.cpp +50 -0
  44. data/ext/libsass/src/backtrace.hpp +29 -0
  45. data/ext/libsass/src/base64vlq.cpp +47 -0
  46. data/ext/libsass/src/base64vlq.hpp +30 -0
  47. data/ext/libsass/src/bind.cpp +312 -0
  48. data/ext/libsass/src/bind.hpp +15 -0
  49. data/ext/libsass/src/c2ast.cpp +64 -0
  50. data/ext/libsass/src/c2ast.hpp +14 -0
  51. data/ext/libsass/src/c99func.c +54 -0
  52. data/ext/libsass/src/cencode.c +106 -0
  53. data/ext/libsass/src/check_nesting.cpp +393 -0
  54. data/ext/libsass/src/check_nesting.hpp +70 -0
  55. data/ext/libsass/src/color_maps.cpp +652 -0
  56. data/ext/libsass/src/color_maps.hpp +323 -0
  57. data/ext/libsass/src/color_spaces.cpp +241 -0
  58. data/ext/libsass/src/color_spaces.hpp +227 -0
  59. data/ext/libsass/src/constants.cpp +199 -0
  60. data/ext/libsass/src/constants.hpp +200 -0
  61. data/ext/libsass/src/context.cpp +870 -0
  62. data/ext/libsass/src/context.hpp +140 -0
  63. data/ext/libsass/src/cssize.cpp +521 -0
  64. data/ext/libsass/src/cssize.hpp +71 -0
  65. data/ext/libsass/src/dart_helpers.hpp +199 -0
  66. data/ext/libsass/src/debug.hpp +43 -0
  67. data/ext/libsass/src/debugger.hpp +964 -0
  68. data/ext/libsass/src/emitter.cpp +297 -0
  69. data/ext/libsass/src/emitter.hpp +101 -0
  70. data/ext/libsass/src/environment.cpp +260 -0
  71. data/ext/libsass/src/environment.hpp +124 -0
  72. data/ext/libsass/src/error_handling.cpp +239 -0
  73. data/ext/libsass/src/error_handling.hpp +248 -0
  74. data/ext/libsass/src/eval.cpp +1543 -0
  75. data/ext/libsass/src/eval.hpp +110 -0
  76. data/ext/libsass/src/eval_selectors.cpp +75 -0
  77. data/ext/libsass/src/expand.cpp +875 -0
  78. data/ext/libsass/src/expand.hpp +98 -0
  79. data/ext/libsass/src/extender.cpp +1226 -0
  80. data/ext/libsass/src/extender.hpp +399 -0
  81. data/ext/libsass/src/extension.cpp +43 -0
  82. data/ext/libsass/src/extension.hpp +89 -0
  83. data/ext/libsass/src/file.cpp +531 -0
  84. data/ext/libsass/src/file.hpp +124 -0
  85. data/ext/libsass/src/fn_colors.cpp +836 -0
  86. data/ext/libsass/src/fn_colors.hpp +99 -0
  87. data/ext/libsass/src/fn_lists.cpp +285 -0
  88. data/ext/libsass/src/fn_lists.hpp +34 -0
  89. data/ext/libsass/src/fn_maps.cpp +94 -0
  90. data/ext/libsass/src/fn_maps.hpp +30 -0
  91. data/ext/libsass/src/fn_miscs.cpp +248 -0
  92. data/ext/libsass/src/fn_miscs.hpp +40 -0
  93. data/ext/libsass/src/fn_numbers.cpp +246 -0
  94. data/ext/libsass/src/fn_numbers.hpp +45 -0
  95. data/ext/libsass/src/fn_selectors.cpp +205 -0
  96. data/ext/libsass/src/fn_selectors.hpp +35 -0
  97. data/ext/libsass/src/fn_strings.cpp +268 -0
  98. data/ext/libsass/src/fn_strings.hpp +34 -0
  99. data/ext/libsass/src/fn_utils.cpp +159 -0
  100. data/ext/libsass/src/fn_utils.hpp +62 -0
  101. data/ext/libsass/src/inspect.cpp +1126 -0
  102. data/ext/libsass/src/inspect.hpp +101 -0
  103. data/ext/libsass/src/json.cpp +1436 -0
  104. data/ext/libsass/src/json.hpp +117 -0
  105. data/ext/libsass/src/kwd_arg_macros.hpp +28 -0
  106. data/ext/libsass/src/lexer.cpp +122 -0
  107. data/ext/libsass/src/lexer.hpp +304 -0
  108. data/ext/libsass/src/listize.cpp +70 -0
  109. data/ext/libsass/src/listize.hpp +37 -0
  110. data/ext/libsass/src/mapping.hpp +19 -0
  111. data/ext/libsass/src/memory/allocator.cpp +48 -0
  112. data/ext/libsass/src/memory/allocator.hpp +138 -0
  113. data/ext/libsass/src/memory/config.hpp +20 -0
  114. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  115. data/ext/libsass/src/memory/shared_ptr.cpp +33 -0
  116. data/ext/libsass/src/memory/shared_ptr.hpp +332 -0
  117. data/ext/libsass/src/memory.hpp +12 -0
  118. data/ext/libsass/src/operation.hpp +223 -0
  119. data/ext/libsass/src/operators.cpp +267 -0
  120. data/ext/libsass/src/operators.hpp +30 -0
  121. data/ext/libsass/src/ordered_map.hpp +112 -0
  122. data/ext/libsass/src/output.cpp +320 -0
  123. data/ext/libsass/src/output.hpp +47 -0
  124. data/ext/libsass/src/parser.cpp +3059 -0
  125. data/ext/libsass/src/parser.hpp +395 -0
  126. data/ext/libsass/src/parser_selectors.cpp +189 -0
  127. data/ext/libsass/src/permutate.hpp +164 -0
  128. data/ext/libsass/src/plugins.cpp +188 -0
  129. data/ext/libsass/src/plugins.hpp +57 -0
  130. data/ext/libsass/src/position.cpp +163 -0
  131. data/ext/libsass/src/position.hpp +147 -0
  132. data/ext/libsass/src/prelexer.cpp +1780 -0
  133. data/ext/libsass/src/prelexer.hpp +484 -0
  134. data/ext/libsass/src/remove_placeholders.cpp +86 -0
  135. data/ext/libsass/src/remove_placeholders.hpp +37 -0
  136. data/ext/libsass/src/sass.cpp +156 -0
  137. data/ext/libsass/src/sass.hpp +147 -0
  138. data/ext/libsass/src/sass2scss.cpp +895 -0
  139. data/ext/libsass/src/sass_context.cpp +742 -0
  140. data/ext/libsass/src/sass_context.hpp +129 -0
  141. data/ext/libsass/src/sass_functions.cpp +210 -0
  142. data/ext/libsass/src/sass_functions.hpp +50 -0
  143. data/ext/libsass/src/sass_values.cpp +362 -0
  144. data/ext/libsass/src/sass_values.hpp +82 -0
  145. data/ext/libsass/src/settings.hpp +19 -0
  146. data/ext/libsass/src/source.cpp +69 -0
  147. data/ext/libsass/src/source.hpp +95 -0
  148. data/ext/libsass/src/source_data.hpp +32 -0
  149. data/ext/libsass/src/source_map.cpp +202 -0
  150. data/ext/libsass/src/source_map.hpp +65 -0
  151. data/ext/libsass/src/stylesheet.cpp +22 -0
  152. data/ext/libsass/src/stylesheet.hpp +57 -0
  153. data/ext/libsass/src/to_value.cpp +114 -0
  154. data/ext/libsass/src/to_value.hpp +46 -0
  155. data/ext/libsass/src/units.cpp +507 -0
  156. data/ext/libsass/src/units.hpp +110 -0
  157. data/ext/libsass/src/utf8/checked.h +336 -0
  158. data/ext/libsass/src/utf8/core.h +332 -0
  159. data/ext/libsass/src/utf8/unchecked.h +235 -0
  160. data/ext/libsass/src/utf8.h +34 -0
  161. data/ext/libsass/src/utf8_string.cpp +104 -0
  162. data/ext/libsass/src/utf8_string.hpp +38 -0
  163. data/ext/libsass/src/util.cpp +723 -0
  164. data/ext/libsass/src/util.hpp +105 -0
  165. data/ext/libsass/src/util_string.cpp +125 -0
  166. data/ext/libsass/src/util_string.hpp +73 -0
  167. data/ext/libsass/src/values.cpp +140 -0
  168. data/ext/libsass/src/values.hpp +12 -0
  169. data/lib/sassc/dependency.rb +17 -0
  170. data/lib/sassc/engine.rb +141 -0
  171. data/lib/sassc/error.rb +37 -0
  172. data/lib/sassc/functions_handler.rb +73 -0
  173. data/lib/sassc/import_handler.rb +50 -0
  174. data/lib/sassc/importer.rb +31 -0
  175. data/lib/sassc/native/native_context_api.rb +147 -0
  176. data/lib/sassc/native/native_functions_api.rb +159 -0
  177. data/lib/sassc/native/sass2scss_api.rb +10 -0
  178. data/lib/sassc/native/sass_input_style.rb +13 -0
  179. data/lib/sassc/native/sass_output_style.rb +12 -0
  180. data/lib/sassc/native/sass_value.rb +97 -0
  181. data/lib/sassc/native/string_list.rb +10 -0
  182. data/lib/sassc/native.rb +64 -0
  183. data/lib/sassc/sass_2_scss.rb +9 -0
  184. data/lib/sassc/script/functions.rb +8 -0
  185. data/lib/sassc/script/value/bool.rb +32 -0
  186. data/lib/sassc/script/value/color.rb +95 -0
  187. data/lib/sassc/script/value/list.rb +136 -0
  188. data/lib/sassc/script/value/map.rb +69 -0
  189. data/lib/sassc/script/value/number.rb +389 -0
  190. data/lib/sassc/script/value/string.rb +96 -0
  191. data/lib/sassc/script/value.rb +137 -0
  192. data/lib/sassc/script/value_conversion/base.rb +13 -0
  193. data/lib/sassc/script/value_conversion/bool.rb +13 -0
  194. data/lib/sassc/script/value_conversion/color.rb +18 -0
  195. data/lib/sassc/script/value_conversion/list.rb +25 -0
  196. data/lib/sassc/script/value_conversion/map.rb +21 -0
  197. data/lib/sassc/script/value_conversion/number.rb +13 -0
  198. data/lib/sassc/script/value_conversion/string.rb +17 -0
  199. data/lib/sassc/script/value_conversion.rb +69 -0
  200. data/lib/sassc/script.rb +17 -0
  201. data/lib/sassc/util/normalized_map.rb +117 -0
  202. data/lib/sassc/util.rb +231 -0
  203. data/lib/sassc/version.rb +5 -0
  204. data/lib/sassc.rb +57 -0
  205. data/sassc.gemspec +69 -0
  206. data/test/css_color_level4_test.rb +168 -0
  207. data/test/custom_importer_test.rb +127 -0
  208. data/test/engine_test.rb +314 -0
  209. data/test/error_test.rb +29 -0
  210. data/test/fixtures/paths.scss +10 -0
  211. data/test/functions_test.rb +340 -0
  212. data/test/native_test.rb +213 -0
  213. data/test/output_style_test.rb +107 -0
  214. data/test/sass_2_scss_test.rb +14 -0
  215. data/test/test_helper.rb +45 -0
  216. metadata +396 -0
@@ -0,0 +1,1070 @@
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 "permutate.hpp"
7
+ #include "util_string.hpp"
8
+
9
+ namespace Sass {
10
+
11
+ /////////////////////////////////////////////////////////////////////////
12
+ /////////////////////////////////////////////////////////////////////////
13
+
14
+ Selector::Selector(SourceSpan pstate)
15
+ : Expression(pstate),
16
+ hash_(0)
17
+ { concrete_type(SELECTOR); }
18
+
19
+ Selector::Selector(const Selector* ptr)
20
+ : Expression(ptr),
21
+ hash_(ptr->hash_)
22
+ { concrete_type(SELECTOR); }
23
+
24
+
25
+ bool Selector::has_real_parent_ref() const
26
+ {
27
+ return false;
28
+ }
29
+
30
+ /////////////////////////////////////////////////////////////////////////
31
+ /////////////////////////////////////////////////////////////////////////
32
+
33
+ Selector_Schema::Selector_Schema(SourceSpan pstate, String_Obj c)
34
+ : AST_Node(pstate),
35
+ contents_(c),
36
+ connect_parent_(true),
37
+ hash_(0)
38
+ { }
39
+ Selector_Schema::Selector_Schema(const Selector_Schema* ptr)
40
+ : AST_Node(ptr),
41
+ contents_(ptr->contents_),
42
+ connect_parent_(ptr->connect_parent_),
43
+ hash_(ptr->hash_)
44
+ { }
45
+
46
+ unsigned long Selector_Schema::specificity() const
47
+ {
48
+ return 0;
49
+ }
50
+
51
+ size_t Selector_Schema::hash() const {
52
+ if (hash_ == 0) {
53
+ hash_combine(hash_, contents_->hash());
54
+ }
55
+ return hash_;
56
+ }
57
+
58
+ bool Selector_Schema::has_real_parent_ref() const
59
+ {
60
+ // Note: disabled since it does not seem to do anything?
61
+ // if (String_Schema_Obj schema = Cast<String_Schema>(contents())) {
62
+ // if (schema->empty()) return false;
63
+ // const auto first = schema->first();
64
+ // return Cast<Parent_Reference>(first);
65
+ // }
66
+ return false;
67
+ }
68
+
69
+ /////////////////////////////////////////////////////////////////////////
70
+ /////////////////////////////////////////////////////////////////////////
71
+
72
+ SimpleSelector::SimpleSelector(SourceSpan pstate, sass::string n)
73
+ : Selector(pstate), ns_(""), name_(n), has_ns_(false)
74
+ {
75
+ size_t pos = n.find('|');
76
+ // found some namespace
77
+ if (pos != sass::string::npos) {
78
+ has_ns_ = true;
79
+ ns_ = n.substr(0, pos);
80
+ name_ = n.substr(pos + 1);
81
+ }
82
+ }
83
+ SimpleSelector::SimpleSelector(const SimpleSelector* ptr)
84
+ : Selector(ptr),
85
+ ns_(ptr->ns_),
86
+ name_(ptr->name_),
87
+ has_ns_(ptr->has_ns_)
88
+ { }
89
+
90
+ sass::string SimpleSelector::ns_name() const
91
+ {
92
+ if (!has_ns_) return name_;
93
+ else return ns_ + "|" + name_;
94
+ }
95
+
96
+ size_t SimpleSelector::hash() const
97
+ {
98
+ if (hash_ == 0) {
99
+ hash_combine(hash_, name());
100
+ hash_combine(hash_, (int)SELECTOR);
101
+ hash_combine(hash_, (int)simple_type());
102
+ if (has_ns_) hash_combine(hash_, ns());
103
+ }
104
+ return hash_;
105
+ }
106
+
107
+ bool SimpleSelector::empty() const {
108
+ return ns().empty() && name().empty();
109
+ }
110
+
111
+ // namespace compare functions
112
+ bool SimpleSelector::is_ns_eq(const SimpleSelector& r) const
113
+ {
114
+ return has_ns_ == r.has_ns_ && ns_ == r.ns_;
115
+ }
116
+
117
+ // namespace query functions
118
+ bool SimpleSelector::is_universal_ns() const
119
+ {
120
+ return has_ns_ && ns_ == "*";
121
+ }
122
+
123
+ bool SimpleSelector::is_empty_ns() const
124
+ {
125
+ return !has_ns_ || ns_ == "";
126
+ }
127
+
128
+ bool SimpleSelector::has_empty_ns() const
129
+ {
130
+ return has_ns_ && ns_ == "";
131
+ }
132
+
133
+ bool SimpleSelector::has_qualified_ns() const
134
+ {
135
+ return has_ns_ && ns_ != "" && ns_ != "*";
136
+ }
137
+
138
+ // name query functions
139
+ bool SimpleSelector::is_universal() const
140
+ {
141
+ return name_ == "*";
142
+ }
143
+
144
+ bool SimpleSelector::has_placeholder()
145
+ {
146
+ return false;
147
+ }
148
+
149
+ bool SimpleSelector::has_real_parent_ref() const
150
+ {
151
+ return false;
152
+ };
153
+
154
+ bool SimpleSelector::is_pseudo_element() const
155
+ {
156
+ return false;
157
+ }
158
+
159
+ CompoundSelectorObj SimpleSelector::wrapInCompound()
160
+ {
161
+ CompoundSelectorObj selector =
162
+ SASS_MEMORY_NEW(CompoundSelector, pstate());
163
+ selector->append(this);
164
+ return selector;
165
+ }
166
+ ComplexSelectorObj SimpleSelector::wrapInComplex()
167
+ {
168
+ ComplexSelectorObj selector =
169
+ SASS_MEMORY_NEW(ComplexSelector, pstate());
170
+ selector->append(wrapInCompound());
171
+ return selector;
172
+ }
173
+
174
+ /////////////////////////////////////////////////////////////////////////
175
+ /////////////////////////////////////////////////////////////////////////
176
+
177
+ PlaceholderSelector::PlaceholderSelector(SourceSpan pstate, sass::string n)
178
+ : SimpleSelector(pstate, n)
179
+ { simple_type(PLACEHOLDER_SEL); }
180
+ PlaceholderSelector::PlaceholderSelector(const PlaceholderSelector* ptr)
181
+ : SimpleSelector(ptr)
182
+ { simple_type(PLACEHOLDER_SEL); }
183
+ unsigned long PlaceholderSelector::specificity() const
184
+ {
185
+ return Constants::Specificity_Base;
186
+ }
187
+ bool PlaceholderSelector::has_placeholder() {
188
+ return true;
189
+ }
190
+
191
+ /////////////////////////////////////////////////////////////////////////
192
+ /////////////////////////////////////////////////////////////////////////
193
+
194
+ TypeSelector::TypeSelector(SourceSpan pstate, sass::string n)
195
+ : SimpleSelector(pstate, n)
196
+ { simple_type(TYPE_SEL); }
197
+ TypeSelector::TypeSelector(const TypeSelector* ptr)
198
+ : SimpleSelector(ptr)
199
+ { simple_type(TYPE_SEL); }
200
+
201
+ unsigned long TypeSelector::specificity() const
202
+ {
203
+ if (name() == "*") return 0;
204
+ else return Constants::Specificity_Element;
205
+ }
206
+
207
+ /////////////////////////////////////////////////////////////////////////
208
+ /////////////////////////////////////////////////////////////////////////
209
+
210
+ ClassSelector::ClassSelector(SourceSpan pstate, sass::string n)
211
+ : SimpleSelector(pstate, n)
212
+ { simple_type(CLASS_SEL); }
213
+ ClassSelector::ClassSelector(const ClassSelector* ptr)
214
+ : SimpleSelector(ptr)
215
+ { simple_type(CLASS_SEL); }
216
+
217
+ unsigned long ClassSelector::specificity() const
218
+ {
219
+ return Constants::Specificity_Class;
220
+ }
221
+
222
+ /////////////////////////////////////////////////////////////////////////
223
+ /////////////////////////////////////////////////////////////////////////
224
+
225
+ IDSelector::IDSelector(SourceSpan pstate, sass::string n)
226
+ : SimpleSelector(pstate, n)
227
+ { simple_type(ID_SEL); }
228
+ IDSelector::IDSelector(const IDSelector* ptr)
229
+ : SimpleSelector(ptr)
230
+ { simple_type(ID_SEL); }
231
+
232
+ unsigned long IDSelector::specificity() const
233
+ {
234
+ return Constants::Specificity_ID;
235
+ }
236
+
237
+ /////////////////////////////////////////////////////////////////////////
238
+ /////////////////////////////////////////////////////////////////////////
239
+
240
+ AttributeSelector::AttributeSelector(SourceSpan pstate, sass::string n, sass::string m, String_Obj v, char o)
241
+ : SimpleSelector(pstate, n), matcher_(m), value_(v), modifier_(o)
242
+ { simple_type(ATTRIBUTE_SEL); }
243
+ AttributeSelector::AttributeSelector(const AttributeSelector* ptr)
244
+ : SimpleSelector(ptr),
245
+ matcher_(ptr->matcher_),
246
+ value_(ptr->value_),
247
+ modifier_(ptr->modifier_)
248
+ { simple_type(ATTRIBUTE_SEL); }
249
+
250
+ size_t AttributeSelector::hash() const
251
+ {
252
+ if (hash_ == 0) {
253
+ hash_combine(hash_, SimpleSelector::hash());
254
+ hash_combine(hash_, std::hash<sass::string>()(matcher()));
255
+ if (value_) hash_combine(hash_, value_->hash());
256
+ }
257
+ return hash_;
258
+ }
259
+
260
+ unsigned long AttributeSelector::specificity() const
261
+ {
262
+ return Constants::Specificity_Attr;
263
+ }
264
+
265
+ /////////////////////////////////////////////////////////////////////////
266
+ /////////////////////////////////////////////////////////////////////////
267
+
268
+ PseudoSelector::PseudoSelector(SourceSpan pstate, sass::string name, bool element)
269
+ : SimpleSelector(pstate, name),
270
+ normalized_(Util::unvendor(name)),
271
+ argument_({}),
272
+ selector_({}),
273
+ isSyntacticClass_(!element),
274
+ isClass_(!element && !isFakePseudoElement(normalized_))
275
+ { simple_type(PSEUDO_SEL); }
276
+ PseudoSelector::PseudoSelector(const PseudoSelector* ptr)
277
+ : SimpleSelector(ptr),
278
+ normalized_(ptr->normalized()),
279
+ argument_(ptr->argument()),
280
+ selector_(ptr->selector()),
281
+ isSyntacticClass_(ptr->isSyntacticClass()),
282
+ isClass_(ptr->isClass())
283
+ { simple_type(PSEUDO_SEL); }
284
+
285
+ // A pseudo-element is made of two colons (::) followed by the name.
286
+ // The `::` notation is introduced by the current document in order to
287
+ // establish a discrimination between pseudo-classes and pseudo-elements.
288
+ // For compatibility with existing style sheets, user agents must also
289
+ // accept the previous one-colon notation for pseudo-elements introduced
290
+ // in CSS levels 1 and 2 (namely, :first-line, :first-letter, :before and
291
+ // :after). This compatibility is not allowed for the new pseudo-elements
292
+ // introduced in this specification.
293
+ bool PseudoSelector::is_pseudo_element() const
294
+ {
295
+ return isElement();
296
+ }
297
+
298
+ size_t PseudoSelector::hash() const
299
+ {
300
+ if (hash_ == 0) {
301
+ hash_combine(hash_, SimpleSelector::hash());
302
+ if (selector_) hash_combine(hash_, selector_->hash());
303
+ if (argument_) hash_combine(hash_, argument_->hash());
304
+ }
305
+ return hash_;
306
+ }
307
+
308
+ unsigned long PseudoSelector::specificity() const
309
+ {
310
+ if (is_pseudo_element())
311
+ return Constants::Specificity_Element;
312
+ return Constants::Specificity_Pseudo;
313
+ }
314
+
315
+ PseudoSelectorObj PseudoSelector::withSelector(SelectorListObj selector)
316
+ {
317
+ PseudoSelectorObj pseudo = SASS_MEMORY_COPY(this);
318
+ pseudo->selector(selector);
319
+ return pseudo;
320
+ }
321
+
322
+ bool PseudoSelector::empty() const
323
+ {
324
+ // Only considered empty if selector is
325
+ // available but has no items in it.
326
+ return selector() && selector()->empty();
327
+ }
328
+
329
+ void PseudoSelector::cloneChildren()
330
+ {
331
+ if (selector().isNull()) selector({});
332
+ else selector(SASS_MEMORY_CLONE(selector()));
333
+ }
334
+
335
+ bool PseudoSelector::has_real_parent_ref() const {
336
+ if (!selector()) return false;
337
+ return selector()->has_real_parent_ref();
338
+ }
339
+
340
+ /////////////////////////////////////////////////////////////////////////
341
+ /////////////////////////////////////////////////////////////////////////
342
+
343
+ SelectorList::SelectorList(SourceSpan pstate, size_t s)
344
+ : Selector(pstate),
345
+ Vectorized<ComplexSelectorObj>(s),
346
+ is_optional_(false)
347
+ { }
348
+ SelectorList::SelectorList(const SelectorList* ptr)
349
+ : Selector(ptr),
350
+ Vectorized<ComplexSelectorObj>(*ptr),
351
+ is_optional_(ptr->is_optional_)
352
+ { }
353
+
354
+ size_t SelectorList::hash() const
355
+ {
356
+ if (Selector::hash_ == 0) {
357
+ hash_combine(Selector::hash_, Vectorized::hash());
358
+ }
359
+ return Selector::hash_;
360
+ }
361
+
362
+ bool SelectorList::has_real_parent_ref() const
363
+ {
364
+ for (ComplexSelectorObj s : elements()) {
365
+ if (s && s->has_real_parent_ref()) return true;
366
+ }
367
+ return false;
368
+ }
369
+
370
+ void SelectorList::cloneChildren()
371
+ {
372
+ for (size_t i = 0, l = length(); i < l; i++) {
373
+ at(i) = SASS_MEMORY_CLONE(at(i));
374
+ }
375
+ }
376
+
377
+ unsigned long SelectorList::specificity() const
378
+ {
379
+ return 0;
380
+ }
381
+
382
+ bool SelectorList::isInvisible() const
383
+ {
384
+ if (length() == 0) return true;
385
+ for (size_t i = 0; i < length(); i += 1) {
386
+ if (get(i)->isInvisible()) return true;
387
+ }
388
+ return false;
389
+ }
390
+
391
+ /////////////////////////////////////////////////////////////////////////
392
+ /////////////////////////////////////////////////////////////////////////
393
+
394
+ ComplexSelector::ComplexSelector(SourceSpan pstate)
395
+ : Selector(pstate),
396
+ Vectorized<SelectorComponentObj>(),
397
+ chroots_(false),
398
+ hasPreLineFeed_(false)
399
+ {
400
+ }
401
+ ComplexSelector::ComplexSelector(const ComplexSelector* ptr)
402
+ : Selector(ptr),
403
+ Vectorized<SelectorComponentObj>(ptr->elements()),
404
+ chroots_(ptr->chroots()),
405
+ hasPreLineFeed_(ptr->hasPreLineFeed())
406
+ {
407
+ }
408
+
409
+ void ComplexSelector::cloneChildren()
410
+ {
411
+ for (size_t i = 0, l = length(); i < l; i++) {
412
+ at(i) = SASS_MEMORY_CLONE(at(i));
413
+ }
414
+ }
415
+
416
+ unsigned long ComplexSelector::specificity() const
417
+ {
418
+ int sum = 0;
419
+ for (auto component : elements()) {
420
+ sum += component->specificity();
421
+ }
422
+ return sum;
423
+ }
424
+
425
+ bool ComplexSelector::isInvisible() const
426
+ {
427
+ if (length() == 0) return true;
428
+ for (size_t i = 0; i < length(); i += 1) {
429
+ if (CompoundSelectorObj compound = get(i)->getCompound()) {
430
+ if (compound->isInvisible()) return true;
431
+ }
432
+ }
433
+ return false;
434
+ }
435
+
436
+ bool ComplexSelector::isInvalidCss() const
437
+ {
438
+ for (size_t i = 0; i < length(); i += 1) {
439
+ if (CompoundSelectorObj compound = get(i)->getCompound()) {
440
+ if (compound->isInvalidCss()) return true;
441
+ }
442
+ }
443
+ return false;
444
+ }
445
+
446
+ SelectorListObj ComplexSelector::wrapInList()
447
+ {
448
+ SelectorListObj selector =
449
+ SASS_MEMORY_NEW(SelectorList, pstate());
450
+ selector->append(this);
451
+ return selector;
452
+ }
453
+
454
+ size_t ComplexSelector::hash() const
455
+ {
456
+ if (Selector::hash_ == 0) {
457
+ hash_combine(Selector::hash_, Vectorized::hash());
458
+ // ToDo: this breaks some extend lookup
459
+ // hash_combine(Selector::hash_, chroots_);
460
+ }
461
+ return Selector::hash_;
462
+ }
463
+
464
+ bool ComplexSelector::has_placeholder() const {
465
+ for (size_t i = 0, L = length(); i < L; ++i) {
466
+ if (get(i)->has_placeholder()) return true;
467
+ }
468
+ return false;
469
+ }
470
+
471
+ bool ComplexSelector::has_real_parent_ref() const
472
+ {
473
+ for (auto item : elements()) {
474
+ if (item->has_real_parent_ref()) return true;
475
+ }
476
+ return false;
477
+ }
478
+
479
+ /////////////////////////////////////////////////////////////////////////
480
+ /////////////////////////////////////////////////////////////////////////
481
+
482
+ SelectorComponent::SelectorComponent(SourceSpan pstate, bool postLineBreak)
483
+ : Selector(pstate),
484
+ hasPostLineBreak_(postLineBreak)
485
+ {
486
+ }
487
+
488
+ SelectorComponent::SelectorComponent(const SelectorComponent* ptr)
489
+ : Selector(ptr),
490
+ hasPostLineBreak_(ptr->hasPostLineBreak())
491
+ { }
492
+
493
+ void SelectorComponent::cloneChildren()
494
+ {
495
+ }
496
+
497
+ unsigned long SelectorComponent::specificity() const
498
+ {
499
+ return 0;
500
+ }
501
+
502
+ // Wrap the compound selector with a complex selector
503
+ ComplexSelector* SelectorComponent::wrapInComplex()
504
+ {
505
+ auto complex = SASS_MEMORY_NEW(ComplexSelector, pstate());
506
+ complex->append(this);
507
+ return complex;
508
+ }
509
+
510
+ /////////////////////////////////////////////////////////////////////////
511
+ /////////////////////////////////////////////////////////////////////////
512
+
513
+ SelectorCombinator::SelectorCombinator(SourceSpan pstate, SelectorCombinator::Combinator combinator, bool postLineBreak)
514
+ : SelectorComponent(pstate, postLineBreak),
515
+ combinator_(combinator)
516
+ {
517
+ }
518
+ SelectorCombinator::SelectorCombinator(const SelectorCombinator* ptr)
519
+ : SelectorComponent(ptr->pstate(), false),
520
+ combinator_(ptr->combinator())
521
+ { }
522
+
523
+ void SelectorCombinator::cloneChildren()
524
+ {
525
+ }
526
+
527
+ unsigned long SelectorCombinator::specificity() const
528
+ {
529
+ return 0;
530
+ }
531
+
532
+ /////////////////////////////////////////////////////////////////////////
533
+ /////////////////////////////////////////////////////////////////////////
534
+
535
+ CompoundSelector::CompoundSelector(SourceSpan pstate, bool postLineBreak)
536
+ : SelectorComponent(pstate, postLineBreak),
537
+ Vectorized<SimpleSelectorObj>(),
538
+ hasRealParent_(false)
539
+ {
540
+ }
541
+ CompoundSelector::CompoundSelector(const CompoundSelector* ptr)
542
+ : SelectorComponent(ptr),
543
+ Vectorized<SimpleSelectorObj>(*ptr),
544
+ hasRealParent_(ptr->hasRealParent())
545
+ { }
546
+
547
+ size_t CompoundSelector::hash() const
548
+ {
549
+ if (Selector::hash_ == 0) {
550
+ hash_combine(Selector::hash_, Vectorized::hash());
551
+ hash_combine(Selector::hash_, hasRealParent_);
552
+ }
553
+ return Selector::hash_;
554
+ }
555
+
556
+ bool CompoundSelector::has_real_parent_ref() const
557
+ {
558
+ if (hasRealParent()) return true;
559
+ // ToDo: dart sass has another check?
560
+ // if (Cast<TypeSelector>(front)) {
561
+ // if (front->ns() != "") return false;
562
+ // }
563
+ for (const SimpleSelector* s : elements()) {
564
+ if (s && s->has_real_parent_ref()) return true;
565
+ }
566
+ return false;
567
+ }
568
+
569
+ bool CompoundSelector::has_placeholder() const
570
+ {
571
+ if (length() == 0) return false;
572
+ for (SimpleSelectorObj ss : elements()) {
573
+ if (ss->has_placeholder()) return true;
574
+ }
575
+ return false;
576
+ }
577
+
578
+ void CompoundSelector::cloneChildren()
579
+ {
580
+ for (size_t i = 0, l = length(); i < l; i++) {
581
+ at(i) = SASS_MEMORY_CLONE(at(i));
582
+ }
583
+ }
584
+
585
+ unsigned long CompoundSelector::specificity() const
586
+ {
587
+ int sum = 0;
588
+ for (size_t i = 0, L = length(); i < L; ++i)
589
+ { sum += get(i)->specificity(); }
590
+ return sum;
591
+ }
592
+
593
+ bool CompoundSelector::isInvisible() const
594
+ {
595
+ for (size_t i = 0; i < length(); i += 1) {
596
+ if (!get(i)->isInvisible()) return false;
597
+ }
598
+ return true;
599
+ }
600
+
601
+ bool CompoundSelector::isSuperselectorOf(const CompoundSelector* sub, sass::string wrapped) const
602
+ {
603
+ CompoundSelector* rhs2 = const_cast<CompoundSelector*>(sub);
604
+ CompoundSelector* lhs2 = const_cast<CompoundSelector*>(this);
605
+ return compoundIsSuperselector(lhs2, rhs2, {});
606
+ }
607
+
608
+ /////////////////////////////////////////////////////////////////////////
609
+ /////////////////////////////////////////////////////////////////////////
610
+
611
+ MediaRule::MediaRule(SourceSpan pstate, Block_Obj block) :
612
+ ParentStatement(pstate, block),
613
+ schema_({})
614
+ {
615
+ statement_type(MEDIA);
616
+ }
617
+
618
+ MediaRule::MediaRule(const MediaRule* ptr) :
619
+ ParentStatement(ptr),
620
+ schema_(ptr->schema_)
621
+ {
622
+ statement_type(MEDIA);
623
+ }
624
+
625
+ /////////////////////////////////////////////////////////////////////////
626
+ /////////////////////////////////////////////////////////////////////////
627
+
628
+ CssMediaRule::CssMediaRule(SourceSpan pstate, Block_Obj block) :
629
+ ParentStatement(pstate, block),
630
+ Vectorized()
631
+ {
632
+ statement_type(MEDIA);
633
+ }
634
+
635
+ CssMediaRule::CssMediaRule(const CssMediaRule* ptr) :
636
+ ParentStatement(ptr),
637
+ Vectorized(*ptr)
638
+ {
639
+ statement_type(MEDIA);
640
+ }
641
+
642
+ CssMediaQuery::CssMediaQuery(SourceSpan pstate) :
643
+ AST_Node(pstate),
644
+ modifier_(""),
645
+ type_(""),
646
+ features_()
647
+ {
648
+ }
649
+
650
+ /////////////////////////////////////////////////////////////////////////
651
+ /////////////////////////////////////////////////////////////////////////
652
+
653
+ bool CssMediaQuery::operator==(const CssMediaQuery& rhs) const
654
+ {
655
+ return type_ == rhs.type_
656
+ && modifier_ == rhs.modifier_
657
+ && features_ == rhs.features_;
658
+ }
659
+
660
+ // Implemented after dart-sass (maybe move to other class?)
661
+ CssMediaQuery_Obj CssMediaQuery::merge(CssMediaQuery_Obj& other)
662
+ {
663
+
664
+ sass::string ourType = this->type();
665
+ Util::ascii_str_tolower(&ourType);
666
+
667
+ sass::string theirType = other->type();
668
+ Util::ascii_str_tolower(&theirType);
669
+
670
+ sass::string ourModifier = this->modifier();
671
+ Util::ascii_str_tolower(&ourModifier);
672
+
673
+ sass::string theirModifier = other->modifier();
674
+ Util::ascii_str_tolower(&theirModifier);
675
+
676
+ sass::string type;
677
+ sass::string modifier;
678
+ sass::vector<sass::string> features;
679
+
680
+ if (ourType.empty() && theirType.empty()) {
681
+ CssMediaQuery_Obj query = SASS_MEMORY_NEW(CssMediaQuery, pstate());
682
+ sass::vector<sass::string> f1(this->features());
683
+ sass::vector<sass::string> f2(other->features());
684
+ features.insert(features.end(), f1.begin(), f1.end());
685
+ features.insert(features.end(), f2.begin(), f2.end());
686
+ query->features(features);
687
+ return query;
688
+ }
689
+
690
+ if ((ourModifier == "not") != (theirModifier == "not")) {
691
+ if (ourType == theirType) {
692
+ sass::vector<sass::string> negativeFeatures =
693
+ ourModifier == "not" ? this->features() : other->features();
694
+ sass::vector<sass::string> positiveFeatures =
695
+ ourModifier == "not" ? other->features() : this->features();
696
+
697
+ // If the negative features are a subset of the positive features, the
698
+ // query is empty. For example, `not screen and (color)` has no
699
+ // intersection with `screen and (color) and (grid)`.
700
+ // However, `not screen and (color)` *does* intersect with `screen and
701
+ // (grid)`, because it means `not (screen and (color))` and so it allows
702
+ // a screen with no color but with a grid.
703
+ if (listIsSubsetOrEqual(negativeFeatures, positiveFeatures)) {
704
+ return SASS_MEMORY_NEW(CssMediaQuery, pstate());
705
+ }
706
+ else {
707
+ return {};
708
+ }
709
+ }
710
+ else if (this->matchesAllTypes() || other->matchesAllTypes()) {
711
+ return {};
712
+ }
713
+
714
+ if (ourModifier == "not") {
715
+ modifier = theirModifier;
716
+ type = theirType;
717
+ features = other->features();
718
+ }
719
+ else {
720
+ modifier = ourModifier;
721
+ type = ourType;
722
+ features = this->features();
723
+ }
724
+ }
725
+ else if (ourModifier == "not") {
726
+ SASS_ASSERT(theirModifier == "not", "modifiers not is sync");
727
+
728
+ // CSS has no way of representing "neither screen nor print".
729
+ if (ourType != theirType) return {};
730
+
731
+ auto moreFeatures = this->features().size() > other->features().size()
732
+ ? this->features()
733
+ : other->features();
734
+ auto fewerFeatures = this->features().size() > other->features().size()
735
+ ? other->features()
736
+ : this->features();
737
+
738
+ // If one set of features is a superset of the other,
739
+ // use those features because they're strictly narrower.
740
+ if (listIsSubsetOrEqual(fewerFeatures, moreFeatures)) {
741
+ modifier = ourModifier; // "not"
742
+ type = ourType;
743
+ features = moreFeatures;
744
+ }
745
+ else {
746
+ // Otherwise, there's no way to
747
+ // represent the intersection.
748
+ return {};
749
+ }
750
+
751
+ }
752
+ else {
753
+ if (this->matchesAllTypes()) {
754
+ modifier = theirModifier;
755
+ // Omit the type if either input query did, since that indicates that they
756
+ // aren't targeting a browser that requires "all and".
757
+ type = (other->matchesAllTypes() && ourType.empty()) ? "" : theirType;
758
+ sass::vector<sass::string> f1(this->features());
759
+ sass::vector<sass::string> f2(other->features());
760
+ features.insert(features.end(), f1.begin(), f1.end());
761
+ features.insert(features.end(), f2.begin(), f2.end());
762
+ }
763
+ else if (other->matchesAllTypes()) {
764
+ modifier = ourModifier;
765
+ type = ourType;
766
+ sass::vector<sass::string> f1(this->features());
767
+ sass::vector<sass::string> f2(other->features());
768
+ features.insert(features.end(), f1.begin(), f1.end());
769
+ features.insert(features.end(), f2.begin(), f2.end());
770
+ }
771
+ else if (ourType != theirType) {
772
+ return SASS_MEMORY_NEW(CssMediaQuery, pstate());
773
+ }
774
+ else {
775
+ modifier = ourModifier.empty() ? theirModifier : ourModifier;
776
+ type = ourType;
777
+ sass::vector<sass::string> f1(this->features());
778
+ sass::vector<sass::string> f2(other->features());
779
+ features.insert(features.end(), f1.begin(), f1.end());
780
+ features.insert(features.end(), f2.begin(), f2.end());
781
+ }
782
+ }
783
+
784
+ CssMediaQuery_Obj query = SASS_MEMORY_NEW(CssMediaQuery, pstate());
785
+ query->modifier(modifier == ourModifier ? this->modifier() : other->modifier());
786
+ query->type(ourType.empty() ? other->type() : this->type());
787
+ query->features(features);
788
+ return query;
789
+ }
790
+
791
+ CssMediaQuery::CssMediaQuery(const CssMediaQuery* ptr) :
792
+ AST_Node(*ptr),
793
+ modifier_(ptr->modifier_),
794
+ type_(ptr->type_),
795
+ features_(ptr->features_)
796
+ {
797
+ }
798
+
799
+ /////////////////////////////////////////////////////////////////////////
800
+ // ToDo: finalize specificity implementation
801
+ /////////////////////////////////////////////////////////////////////////
802
+
803
+ size_t SelectorList::maxSpecificity() const
804
+ {
805
+ size_t specificity = 0;
806
+ for (auto complex : elements()) {
807
+ specificity = std::max(specificity, complex->maxSpecificity());
808
+ }
809
+ return specificity;
810
+ }
811
+
812
+ size_t SelectorList::minSpecificity() const
813
+ {
814
+ size_t specificity = 0;
815
+ for (auto complex : elements()) {
816
+ specificity = std::min(specificity, complex->minSpecificity());
817
+ }
818
+ return specificity;
819
+ }
820
+
821
+ size_t CompoundSelector::maxSpecificity() const
822
+ {
823
+ size_t specificity = 0;
824
+ for (auto simple : elements()) {
825
+ specificity += simple->maxSpecificity();
826
+ }
827
+ return specificity;
828
+ }
829
+
830
+ size_t CompoundSelector::minSpecificity() const
831
+ {
832
+ size_t specificity = 0;
833
+ for (auto simple : elements()) {
834
+ specificity += simple->minSpecificity();
835
+ }
836
+ return specificity;
837
+ }
838
+
839
+ size_t ComplexSelector::maxSpecificity() const
840
+ {
841
+ size_t specificity = 0;
842
+ for (auto component : elements()) {
843
+ specificity += component->maxSpecificity();
844
+ }
845
+ return specificity;
846
+ }
847
+
848
+ size_t ComplexSelector::minSpecificity() const
849
+ {
850
+ size_t specificity = 0;
851
+ for (auto component : elements()) {
852
+ specificity += component->minSpecificity();
853
+ }
854
+ return specificity;
855
+ }
856
+
857
+ /////////////////////////////////////////////////////////////////////////
858
+ // ToDo: this might be done easier with new selector format
859
+ /////////////////////////////////////////////////////////////////////////
860
+
861
+ sass::vector<ComplexSelectorObj>
862
+ CompoundSelector::resolve_parent_refs(SelectorStack pstack, Backtraces& traces, bool implicit_parent)
863
+ {
864
+
865
+ auto parent = pstack.back();
866
+ sass::vector<ComplexSelectorObj> rv;
867
+
868
+ for (SimpleSelectorObj simple : elements()) {
869
+ if (PseudoSelector * pseudo = Cast<PseudoSelector>(simple)) {
870
+ if (SelectorList* sel = Cast<SelectorList>(pseudo->selector())) {
871
+ if (parent && !parent->has_real_parent_ref()) {
872
+ pseudo->selector(sel->resolve_parent_refs(
873
+ pstack, traces, implicit_parent));
874
+ }
875
+ }
876
+ }
877
+ }
878
+
879
+ // Mix with parents from stack
880
+ if (hasRealParent()) {
881
+
882
+ if (parent.isNull()) {
883
+ return { wrapInComplex() };
884
+ }
885
+ else {
886
+ for (auto complex : parent->elements()) {
887
+ // The parent complex selector has a compound selector
888
+ if (CompoundSelectorObj tail = Cast<CompoundSelector>(complex->last())) {
889
+ // Create a copy to alter it
890
+ complex = SASS_MEMORY_COPY(complex);
891
+ tail = SASS_MEMORY_COPY(tail);
892
+
893
+ // Check if we can merge front with back
894
+ if (length() > 0 && tail->length() > 0) {
895
+ SimpleSelectorObj back = tail->last();
896
+ SimpleSelectorObj front = first();
897
+ auto simple_back = Cast<SimpleSelector>(back);
898
+ auto simple_front = Cast<TypeSelector>(front);
899
+ if (simple_front && simple_back) {
900
+ simple_back = SASS_MEMORY_COPY(simple_back);
901
+ auto name = simple_back->name();
902
+ name += simple_front->name();
903
+ simple_back->name(name);
904
+ tail->elements().back() = simple_back;
905
+ tail->elements().insert(tail->end(),
906
+ begin() + 1, end());
907
+ }
908
+ else {
909
+ tail->concat(this);
910
+ }
911
+ }
912
+ else {
913
+ tail->concat(this);
914
+ }
915
+
916
+ complex->elements().back() = tail;
917
+ // Append to results
918
+ rv.push_back(complex);
919
+ }
920
+ else {
921
+ // Can't insert parent that ends with a combinator
922
+ // where the parent selector is followed by something
923
+ if (parent && length() > 0) {
924
+ throw Exception::InvalidParent(parent, traces, this);
925
+ }
926
+ // Create a copy to alter it
927
+ complex = SASS_MEMORY_COPY(complex);
928
+ // Just append ourself
929
+ complex->append(this);
930
+ // Append to results
931
+ rv.push_back(complex);
932
+ }
933
+ }
934
+ }
935
+ }
936
+
937
+ // No parents
938
+ else {
939
+ // Create a new wrapper to wrap ourself
940
+ auto complex = SASS_MEMORY_NEW(ComplexSelector, pstate());
941
+ // Just append ourself
942
+ complex->append(this);
943
+ // Append to results
944
+ rv.push_back(complex);
945
+ }
946
+
947
+ return rv;
948
+
949
+ }
950
+
951
+ bool cmpSimpleSelectors(SimpleSelector* a, SimpleSelector* b)
952
+ {
953
+ return (a->getSortOrder() < b->getSortOrder());
954
+ }
955
+
956
+ void CompoundSelector::sortChildren()
957
+ {
958
+ std::sort(begin(), end(), cmpSimpleSelectors);
959
+ }
960
+
961
+ bool CompoundSelector::isInvalidCss() const
962
+ {
963
+ size_t current = 0, next = 0;
964
+ for (const SimpleSelector* sel : elements()) {
965
+ next = sel->getSortOrder();
966
+ // Must only have one type selector
967
+ if (current == 1 && next == 1) {
968
+ return true;
969
+ }
970
+ if (next < current) {
971
+ return true;
972
+ }
973
+ current = next;
974
+ }
975
+ return false;
976
+ }
977
+
978
+ /* better return sass::vector? only - is empty container anyway? */
979
+ SelectorList* ComplexSelector::resolve_parent_refs(
980
+ SelectorStack pstack, Backtraces& traces, bool implicit_parent)
981
+ {
982
+
983
+ sass::vector<sass::vector<ComplexSelectorObj>> vars;
984
+
985
+ auto parent = pstack.back();
986
+ auto hasRealParent = has_real_parent_ref();
987
+
988
+ if (hasRealParent && !parent) {
989
+ throw Exception::TopLevelParent(traces, pstate());
990
+ }
991
+
992
+ if (!chroots() && parent) {
993
+
994
+ if (!hasRealParent && !implicit_parent) {
995
+ SelectorList* retval = SASS_MEMORY_NEW(SelectorList, pstate(), 1);
996
+ retval->append(this);
997
+ return retval;
998
+ }
999
+
1000
+ vars.push_back(parent->elements());
1001
+ }
1002
+
1003
+ for (auto sel : elements()) {
1004
+ if (CompoundSelectorObj comp = Cast<CompoundSelector>(sel)) {
1005
+ auto asd = comp->resolve_parent_refs(pstack, traces, implicit_parent);
1006
+ if (asd.size() > 0) vars.push_back(asd);
1007
+ }
1008
+ else {
1009
+ // ToDo: merge together sequences whenever possible
1010
+ auto cont = SASS_MEMORY_NEW(ComplexSelector, pstate());
1011
+ cont->append(sel);
1012
+ vars.push_back({ cont });
1013
+ }
1014
+ }
1015
+
1016
+ // Need complex selectors to preserve linefeeds
1017
+ sass::vector<sass::vector<ComplexSelectorObj>> res = permutateAlt(vars);
1018
+
1019
+ // std::reverse(std::begin(res), std::end(res));
1020
+
1021
+ auto lst = SASS_MEMORY_NEW(SelectorList, pstate());
1022
+ for (auto items : res) {
1023
+ if (items.size() > 0) {
1024
+ ComplexSelectorObj first = SASS_MEMORY_COPY(items[0]);
1025
+ first->hasPreLineFeed(first->hasPreLineFeed() || (!hasRealParent && hasPreLineFeed()));
1026
+ // ToDo: remove once we know how to handle line feeds
1027
+ // ToDo: currently a mashup between ruby and dart sass
1028
+ // if (hasRealParent) first->has_line_feed(false);
1029
+ // first->has_line_break(first->has_line_break() || has_line_break());
1030
+ first->chroots(true); // has been resolved by now
1031
+ for (size_t i = 1; i < items.size(); i += 1) {
1032
+ first->concat(items[i]);
1033
+ }
1034
+ lst->append(first);
1035
+ }
1036
+ }
1037
+
1038
+ return lst;
1039
+
1040
+ }
1041
+
1042
+ SelectorList* SelectorList::resolve_parent_refs(SelectorStack pstack, Backtraces& traces, bool implicit_parent)
1043
+ {
1044
+ SelectorList* rv = SASS_MEMORY_NEW(SelectorList, pstate());
1045
+ for (auto sel : elements()) {
1046
+ // Note: this one is tricky as we get back a pointer from resolve parents ...
1047
+ SelectorListObj res = sel->resolve_parent_refs(pstack, traces, implicit_parent);
1048
+ // Note: ... and concat will only append the items in elements
1049
+ // Therefore by passing it directly, the container will leak!
1050
+ rv->concat(res);
1051
+ }
1052
+ return rv;
1053
+ }
1054
+
1055
+ /////////////////////////////////////////////////////////////////////////
1056
+ /////////////////////////////////////////////////////////////////////////
1057
+
1058
+ IMPLEMENT_AST_OPERATORS(Selector_Schema);
1059
+ IMPLEMENT_AST_OPERATORS(PlaceholderSelector);
1060
+ IMPLEMENT_AST_OPERATORS(AttributeSelector);
1061
+ IMPLEMENT_AST_OPERATORS(TypeSelector);
1062
+ IMPLEMENT_AST_OPERATORS(ClassSelector);
1063
+ IMPLEMENT_AST_OPERATORS(IDSelector);
1064
+ IMPLEMENT_AST_OPERATORS(PseudoSelector);
1065
+ IMPLEMENT_AST_OPERATORS(SelectorCombinator);
1066
+ IMPLEMENT_AST_OPERATORS(CompoundSelector);
1067
+ IMPLEMENT_AST_OPERATORS(ComplexSelector);
1068
+ IMPLEMENT_AST_OPERATORS(SelectorList);
1069
+
1070
+ }