sassc 2.0.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (260) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.gitmodules +1 -1
  4. data/.travis.yml +9 -3
  5. data/CHANGELOG.md +36 -0
  6. data/CODE_OF_CONDUCT.md +1 -1
  7. data/README.md +1 -1
  8. data/Rakefile +43 -7
  9. data/ext/depend +4 -0
  10. data/ext/extconf.rb +92 -0
  11. data/ext/libsass/VERSION +1 -0
  12. data/ext/libsass/include/sass/base.h +9 -1
  13. data/ext/libsass/include/sass/context.h +5 -1
  14. data/ext/libsass/src/MurmurHash2.hpp +91 -0
  15. data/ext/libsass/src/ast.cpp +755 -2028
  16. data/ext/libsass/src/ast.hpp +492 -2477
  17. data/ext/libsass/src/{to_c.cpp → ast2c.cpp} +22 -16
  18. data/ext/libsass/src/ast2c.hpp +39 -0
  19. data/ext/libsass/src/ast_def_macros.hpp +70 -10
  20. data/ext/libsass/src/ast_fwd_decl.cpp +5 -3
  21. data/ext/libsass/src/ast_fwd_decl.hpp +107 -296
  22. data/ext/libsass/src/ast_helpers.hpp +292 -0
  23. data/ext/libsass/src/ast_sel_cmp.cpp +396 -0
  24. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  25. data/ext/libsass/src/ast_sel_unify.cpp +275 -0
  26. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  27. data/ext/libsass/src/ast_selectors.cpp +1043 -0
  28. data/ext/libsass/src/ast_selectors.hpp +522 -0
  29. data/ext/libsass/src/ast_supports.cpp +114 -0
  30. data/ext/libsass/src/ast_supports.hpp +121 -0
  31. data/ext/libsass/src/ast_values.cpp +1154 -0
  32. data/ext/libsass/src/ast_values.hpp +498 -0
  33. data/ext/libsass/src/backtrace.cpp +11 -7
  34. data/ext/libsass/src/backtrace.hpp +5 -5
  35. data/ext/libsass/src/base64vlq.cpp +5 -2
  36. data/ext/libsass/src/base64vlq.hpp +1 -1
  37. data/ext/libsass/src/bind.cpp +35 -34
  38. data/ext/libsass/src/bind.hpp +3 -1
  39. data/ext/libsass/src/c2ast.cpp +64 -0
  40. data/ext/libsass/src/c2ast.hpp +14 -0
  41. data/ext/libsass/src/cencode.c +4 -6
  42. data/ext/libsass/src/check_nesting.cpp +83 -88
  43. data/ext/libsass/src/check_nesting.hpp +39 -34
  44. data/ext/libsass/src/color_maps.cpp +168 -164
  45. data/ext/libsass/src/color_maps.hpp +152 -160
  46. data/ext/libsass/src/constants.cpp +20 -0
  47. data/ext/libsass/src/constants.hpp +19 -0
  48. data/ext/libsass/src/context.cpp +104 -121
  49. data/ext/libsass/src/context.hpp +43 -55
  50. data/ext/libsass/src/cssize.cpp +103 -188
  51. data/ext/libsass/src/cssize.hpp +45 -51
  52. data/ext/libsass/src/dart_helpers.hpp +199 -0
  53. data/ext/libsass/src/debugger.hpp +524 -361
  54. data/ext/libsass/src/emitter.cpp +26 -26
  55. data/ext/libsass/src/emitter.hpp +20 -18
  56. data/ext/libsass/src/environment.cpp +41 -27
  57. data/ext/libsass/src/environment.hpp +33 -22
  58. data/ext/libsass/src/error_handling.cpp +92 -94
  59. data/ext/libsass/src/error_handling.hpp +73 -50
  60. data/ext/libsass/src/eval.cpp +380 -515
  61. data/ext/libsass/src/eval.hpp +64 -57
  62. data/ext/libsass/src/eval_selectors.cpp +75 -0
  63. data/ext/libsass/src/expand.cpp +322 -263
  64. data/ext/libsass/src/expand.hpp +55 -39
  65. data/ext/libsass/src/extender.cpp +1188 -0
  66. data/ext/libsass/src/extender.hpp +399 -0
  67. data/ext/libsass/src/extension.cpp +43 -0
  68. data/ext/libsass/src/extension.hpp +89 -0
  69. data/ext/libsass/src/file.cpp +134 -88
  70. data/ext/libsass/src/file.hpp +28 -37
  71. data/ext/libsass/src/fn_colors.cpp +596 -0
  72. data/ext/libsass/src/fn_colors.hpp +85 -0
  73. data/ext/libsass/src/fn_lists.cpp +285 -0
  74. data/ext/libsass/src/fn_lists.hpp +34 -0
  75. data/ext/libsass/src/fn_maps.cpp +94 -0
  76. data/ext/libsass/src/fn_maps.hpp +30 -0
  77. data/ext/libsass/src/fn_miscs.cpp +244 -0
  78. data/ext/libsass/src/fn_miscs.hpp +40 -0
  79. data/ext/libsass/src/fn_numbers.cpp +227 -0
  80. data/ext/libsass/src/fn_numbers.hpp +45 -0
  81. data/ext/libsass/src/fn_selectors.cpp +205 -0
  82. data/ext/libsass/src/fn_selectors.hpp +35 -0
  83. data/ext/libsass/src/fn_strings.cpp +268 -0
  84. data/ext/libsass/src/fn_strings.hpp +34 -0
  85. data/ext/libsass/src/fn_utils.cpp +158 -0
  86. data/ext/libsass/src/fn_utils.hpp +62 -0
  87. data/ext/libsass/src/inspect.cpp +253 -266
  88. data/ext/libsass/src/inspect.hpp +72 -74
  89. data/ext/libsass/src/json.cpp +2 -2
  90. data/ext/libsass/src/lexer.cpp +25 -84
  91. data/ext/libsass/src/lexer.hpp +5 -16
  92. data/ext/libsass/src/listize.cpp +27 -43
  93. data/ext/libsass/src/listize.hpp +14 -11
  94. data/ext/libsass/src/mapping.hpp +1 -0
  95. data/ext/libsass/src/memory.hpp +12 -0
  96. data/ext/libsass/src/memory/allocator.cpp +48 -0
  97. data/ext/libsass/src/memory/allocator.hpp +138 -0
  98. data/ext/libsass/src/memory/config.hpp +20 -0
  99. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  100. data/ext/libsass/src/memory/shared_ptr.cpp +33 -0
  101. data/ext/libsass/src/memory/shared_ptr.hpp +332 -0
  102. data/ext/libsass/src/operation.hpp +193 -143
  103. data/ext/libsass/src/operators.cpp +56 -29
  104. data/ext/libsass/src/operators.hpp +11 -11
  105. data/ext/libsass/src/ordered_map.hpp +112 -0
  106. data/ext/libsass/src/output.cpp +59 -75
  107. data/ext/libsass/src/output.hpp +15 -22
  108. data/ext/libsass/src/parser.cpp +662 -818
  109. data/ext/libsass/src/parser.hpp +96 -100
  110. data/ext/libsass/src/parser_selectors.cpp +189 -0
  111. data/ext/libsass/src/permutate.hpp +164 -0
  112. data/ext/libsass/src/plugins.cpp +12 -8
  113. data/ext/libsass/src/plugins.hpp +8 -8
  114. data/ext/libsass/src/position.cpp +10 -26
  115. data/ext/libsass/src/position.hpp +44 -21
  116. data/ext/libsass/src/prelexer.cpp +14 -8
  117. data/ext/libsass/src/prelexer.hpp +9 -9
  118. data/ext/libsass/src/remove_placeholders.cpp +59 -57
  119. data/ext/libsass/src/remove_placeholders.hpp +20 -18
  120. data/ext/libsass/src/sass.cpp +25 -18
  121. data/ext/libsass/src/sass.hpp +22 -14
  122. data/ext/libsass/src/sass2scss.cpp +49 -18
  123. data/ext/libsass/src/sass_context.cpp +104 -132
  124. data/ext/libsass/src/sass_context.hpp +2 -2
  125. data/ext/libsass/src/sass_functions.cpp +7 -4
  126. data/ext/libsass/src/sass_functions.hpp +1 -1
  127. data/ext/libsass/src/sass_values.cpp +26 -21
  128. data/ext/libsass/src/settings.hpp +19 -0
  129. data/ext/libsass/src/source.cpp +69 -0
  130. data/ext/libsass/src/source.hpp +95 -0
  131. data/ext/libsass/src/source_data.hpp +32 -0
  132. data/ext/libsass/src/source_map.cpp +27 -20
  133. data/ext/libsass/src/source_map.hpp +14 -11
  134. data/ext/libsass/src/stylesheet.cpp +22 -0
  135. data/ext/libsass/src/stylesheet.hpp +57 -0
  136. data/ext/libsass/src/to_value.cpp +24 -22
  137. data/ext/libsass/src/to_value.hpp +18 -22
  138. data/ext/libsass/src/units.cpp +28 -22
  139. data/ext/libsass/src/units.hpp +9 -8
  140. data/ext/libsass/src/utf8/checked.h +12 -10
  141. data/ext/libsass/src/utf8/core.h +3 -0
  142. data/ext/libsass/src/utf8_string.cpp +12 -10
  143. data/ext/libsass/src/utf8_string.hpp +7 -6
  144. data/ext/libsass/src/util.cpp +97 -107
  145. data/ext/libsass/src/util.hpp +74 -30
  146. data/ext/libsass/src/util_string.cpp +125 -0
  147. data/ext/libsass/src/util_string.hpp +73 -0
  148. data/ext/libsass/src/values.cpp +33 -24
  149. data/ext/libsass/src/values.hpp +2 -2
  150. data/lib/sassc.rb +24 -0
  151. data/lib/sassc/engine.rb +7 -5
  152. data/lib/sassc/functions_handler.rb +11 -13
  153. data/lib/sassc/native.rb +10 -9
  154. data/lib/sassc/native/native_functions_api.rb +0 -5
  155. data/lib/sassc/script.rb +4 -6
  156. data/lib/sassc/version.rb +1 -1
  157. data/sassc.gemspec +32 -12
  158. data/test/engine_test.rb +32 -2
  159. data/test/functions_test.rb +38 -1
  160. data/test/native_test.rb +4 -4
  161. metadata +95 -109
  162. data/ext/Rakefile +0 -3
  163. data/ext/libsass/.editorconfig +0 -15
  164. data/ext/libsass/.gitattributes +0 -2
  165. data/ext/libsass/.github/CONTRIBUTING.md +0 -65
  166. data/ext/libsass/.github/ISSUE_TEMPLATE.md +0 -54
  167. data/ext/libsass/.gitignore +0 -85
  168. data/ext/libsass/.travis.yml +0 -64
  169. data/ext/libsass/COPYING +0 -25
  170. data/ext/libsass/GNUmakefile.am +0 -88
  171. data/ext/libsass/INSTALL +0 -1
  172. data/ext/libsass/LICENSE +0 -25
  173. data/ext/libsass/Makefile +0 -351
  174. data/ext/libsass/Makefile.conf +0 -55
  175. data/ext/libsass/Readme.md +0 -104
  176. data/ext/libsass/SECURITY.md +0 -10
  177. data/ext/libsass/appveyor.yml +0 -91
  178. data/ext/libsass/configure.ac +0 -138
  179. data/ext/libsass/contrib/libsass.spec +0 -66
  180. data/ext/libsass/docs/README.md +0 -20
  181. data/ext/libsass/docs/api-context-example.md +0 -45
  182. data/ext/libsass/docs/api-context-internal.md +0 -163
  183. data/ext/libsass/docs/api-context.md +0 -295
  184. data/ext/libsass/docs/api-doc.md +0 -215
  185. data/ext/libsass/docs/api-function-example.md +0 -67
  186. data/ext/libsass/docs/api-function-internal.md +0 -8
  187. data/ext/libsass/docs/api-function.md +0 -74
  188. data/ext/libsass/docs/api-importer-example.md +0 -112
  189. data/ext/libsass/docs/api-importer-internal.md +0 -20
  190. data/ext/libsass/docs/api-importer.md +0 -86
  191. data/ext/libsass/docs/api-value-example.md +0 -55
  192. data/ext/libsass/docs/api-value-internal.md +0 -76
  193. data/ext/libsass/docs/api-value.md +0 -154
  194. data/ext/libsass/docs/build-on-darwin.md +0 -27
  195. data/ext/libsass/docs/build-on-gentoo.md +0 -55
  196. data/ext/libsass/docs/build-on-windows.md +0 -139
  197. data/ext/libsass/docs/build-shared-library.md +0 -35
  198. data/ext/libsass/docs/build-with-autotools.md +0 -78
  199. data/ext/libsass/docs/build-with-makefiles.md +0 -68
  200. data/ext/libsass/docs/build-with-mingw.md +0 -107
  201. data/ext/libsass/docs/build-with-visual-studio.md +0 -90
  202. data/ext/libsass/docs/build.md +0 -97
  203. data/ext/libsass/docs/compatibility-plan.md +0 -48
  204. data/ext/libsass/docs/contributing.md +0 -17
  205. data/ext/libsass/docs/custom-functions-internal.md +0 -122
  206. data/ext/libsass/docs/dev-ast-memory.md +0 -223
  207. data/ext/libsass/docs/implementations.md +0 -56
  208. data/ext/libsass/docs/plugins.md +0 -47
  209. data/ext/libsass/docs/setup-environment.md +0 -68
  210. data/ext/libsass/docs/source-map-internals.md +0 -51
  211. data/ext/libsass/docs/trace.md +0 -26
  212. data/ext/libsass/docs/triage.md +0 -17
  213. data/ext/libsass/docs/unicode.md +0 -39
  214. data/ext/libsass/extconf.rb +0 -6
  215. data/ext/libsass/include/sass/version.h.in +0 -12
  216. data/ext/libsass/m4/.gitkeep +0 -0
  217. data/ext/libsass/m4/m4-ax_cxx_compile_stdcxx_11.m4 +0 -167
  218. data/ext/libsass/res/resource.rc +0 -35
  219. data/ext/libsass/script/bootstrap +0 -13
  220. data/ext/libsass/script/branding +0 -10
  221. data/ext/libsass/script/ci-build-libsass +0 -134
  222. data/ext/libsass/script/ci-build-plugin +0 -62
  223. data/ext/libsass/script/ci-install-compiler +0 -6
  224. data/ext/libsass/script/ci-install-deps +0 -20
  225. data/ext/libsass/script/ci-report-coverage +0 -42
  226. data/ext/libsass/script/spec +0 -5
  227. data/ext/libsass/script/tap-driver +0 -652
  228. data/ext/libsass/script/tap-runner +0 -1
  229. data/ext/libsass/script/test-leaks.pl +0 -103
  230. data/ext/libsass/src/GNUmakefile.am +0 -54
  231. data/ext/libsass/src/extend.cpp +0 -2130
  232. data/ext/libsass/src/extend.hpp +0 -86
  233. data/ext/libsass/src/functions.cpp +0 -2234
  234. data/ext/libsass/src/functions.hpp +0 -198
  235. data/ext/libsass/src/memory/SharedPtr.cpp +0 -114
  236. data/ext/libsass/src/memory/SharedPtr.hpp +0 -206
  237. data/ext/libsass/src/node.cpp +0 -319
  238. data/ext/libsass/src/node.hpp +0 -118
  239. data/ext/libsass/src/paths.hpp +0 -71
  240. data/ext/libsass/src/sass_util.cpp +0 -149
  241. data/ext/libsass/src/sass_util.hpp +0 -256
  242. data/ext/libsass/src/subset_map.cpp +0 -55
  243. data/ext/libsass/src/subset_map.hpp +0 -76
  244. data/ext/libsass/src/support/libsass.pc.in +0 -11
  245. data/ext/libsass/src/to_c.hpp +0 -39
  246. data/ext/libsass/test/test_node.cpp +0 -94
  247. data/ext/libsass/test/test_paths.cpp +0 -28
  248. data/ext/libsass/test/test_selector_difference.cpp +0 -25
  249. data/ext/libsass/test/test_specificity.cpp +0 -25
  250. data/ext/libsass/test/test_subset_map.cpp +0 -472
  251. data/ext/libsass/test/test_superselector.cpp +0 -69
  252. data/ext/libsass/test/test_unification.cpp +0 -31
  253. data/ext/libsass/version.sh +0 -10
  254. data/ext/libsass/win/libsass.sln +0 -39
  255. data/ext/libsass/win/libsass.sln.DotSettings +0 -9
  256. data/ext/libsass/win/libsass.targets +0 -118
  257. data/ext/libsass/win/libsass.vcxproj +0 -188
  258. data/ext/libsass/win/libsass.vcxproj.filters +0 -357
  259. data/lib/sassc/native/lib_c.rb +0 -21
  260. data/lib/tasks/libsass.rb +0 -33
@@ -0,0 +1,1043 @@
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
+ SelectorListObj ComplexSelector::wrapInList()
437
+ {
438
+ SelectorListObj selector =
439
+ SASS_MEMORY_NEW(SelectorList, pstate());
440
+ selector->append(this);
441
+ return selector;
442
+ }
443
+
444
+ size_t ComplexSelector::hash() const
445
+ {
446
+ if (Selector::hash_ == 0) {
447
+ hash_combine(Selector::hash_, Vectorized::hash());
448
+ // ToDo: this breaks some extend lookup
449
+ // hash_combine(Selector::hash_, chroots_);
450
+ }
451
+ return Selector::hash_;
452
+ }
453
+
454
+ bool ComplexSelector::has_placeholder() const {
455
+ for (size_t i = 0, L = length(); i < L; ++i) {
456
+ if (get(i)->has_placeholder()) return true;
457
+ }
458
+ return false;
459
+ }
460
+
461
+ bool ComplexSelector::has_real_parent_ref() const
462
+ {
463
+ for (auto item : elements()) {
464
+ if (item->has_real_parent_ref()) return true;
465
+ }
466
+ return false;
467
+ }
468
+
469
+ /////////////////////////////////////////////////////////////////////////
470
+ /////////////////////////////////////////////////////////////////////////
471
+
472
+ SelectorComponent::SelectorComponent(SourceSpan pstate, bool postLineBreak)
473
+ : Selector(pstate),
474
+ hasPostLineBreak_(postLineBreak)
475
+ {
476
+ }
477
+
478
+ SelectorComponent::SelectorComponent(const SelectorComponent* ptr)
479
+ : Selector(ptr),
480
+ hasPostLineBreak_(ptr->hasPostLineBreak())
481
+ { }
482
+
483
+ void SelectorComponent::cloneChildren()
484
+ {
485
+ }
486
+
487
+ unsigned long SelectorComponent::specificity() const
488
+ {
489
+ return 0;
490
+ }
491
+
492
+ // Wrap the compound selector with a complex selector
493
+ ComplexSelector* SelectorComponent::wrapInComplex()
494
+ {
495
+ auto complex = SASS_MEMORY_NEW(ComplexSelector, pstate());
496
+ complex->append(this);
497
+ return complex;
498
+ }
499
+
500
+ /////////////////////////////////////////////////////////////////////////
501
+ /////////////////////////////////////////////////////////////////////////
502
+
503
+ SelectorCombinator::SelectorCombinator(SourceSpan pstate, SelectorCombinator::Combinator combinator, bool postLineBreak)
504
+ : SelectorComponent(pstate, postLineBreak),
505
+ combinator_(combinator)
506
+ {
507
+ }
508
+ SelectorCombinator::SelectorCombinator(const SelectorCombinator* ptr)
509
+ : SelectorComponent(ptr->pstate(), false),
510
+ combinator_(ptr->combinator())
511
+ { }
512
+
513
+ void SelectorCombinator::cloneChildren()
514
+ {
515
+ }
516
+
517
+ unsigned long SelectorCombinator::specificity() const
518
+ {
519
+ return 0;
520
+ }
521
+
522
+ /////////////////////////////////////////////////////////////////////////
523
+ /////////////////////////////////////////////////////////////////////////
524
+
525
+ CompoundSelector::CompoundSelector(SourceSpan pstate, bool postLineBreak)
526
+ : SelectorComponent(pstate, postLineBreak),
527
+ Vectorized<SimpleSelectorObj>(),
528
+ hasRealParent_(false),
529
+ extended_(false)
530
+ {
531
+ }
532
+ CompoundSelector::CompoundSelector(const CompoundSelector* ptr)
533
+ : SelectorComponent(ptr),
534
+ Vectorized<SimpleSelectorObj>(*ptr),
535
+ hasRealParent_(ptr->hasRealParent()),
536
+ extended_(ptr->extended())
537
+ { }
538
+
539
+ size_t CompoundSelector::hash() const
540
+ {
541
+ if (Selector::hash_ == 0) {
542
+ hash_combine(Selector::hash_, Vectorized::hash());
543
+ hash_combine(Selector::hash_, hasRealParent_);
544
+ }
545
+ return Selector::hash_;
546
+ }
547
+
548
+ bool CompoundSelector::has_real_parent_ref() const
549
+ {
550
+ if (hasRealParent()) return true;
551
+ // ToDo: dart sass has another check?
552
+ // if (Cast<TypeSelector>(front)) {
553
+ // if (front->ns() != "") return false;
554
+ // }
555
+ for (const SimpleSelector* s : elements()) {
556
+ if (s && s->has_real_parent_ref()) return true;
557
+ }
558
+ return false;
559
+ }
560
+
561
+ bool CompoundSelector::has_placeholder() const
562
+ {
563
+ if (length() == 0) return false;
564
+ for (SimpleSelectorObj ss : elements()) {
565
+ if (ss->has_placeholder()) return true;
566
+ }
567
+ return false;
568
+ }
569
+
570
+ void CompoundSelector::cloneChildren()
571
+ {
572
+ for (size_t i = 0, l = length(); i < l; i++) {
573
+ at(i) = SASS_MEMORY_CLONE(at(i));
574
+ }
575
+ }
576
+
577
+ unsigned long CompoundSelector::specificity() const
578
+ {
579
+ int sum = 0;
580
+ for (size_t i = 0, L = length(); i < L; ++i)
581
+ { sum += get(i)->specificity(); }
582
+ return sum;
583
+ }
584
+
585
+ bool CompoundSelector::isInvisible() const
586
+ {
587
+ for (size_t i = 0; i < length(); i += 1) {
588
+ if (!get(i)->isInvisible()) return false;
589
+ }
590
+ return true;
591
+ }
592
+
593
+ bool CompoundSelector::isSuperselectorOf(const CompoundSelector* sub, sass::string wrapped) const
594
+ {
595
+ CompoundSelector* rhs2 = const_cast<CompoundSelector*>(sub);
596
+ CompoundSelector* lhs2 = const_cast<CompoundSelector*>(this);
597
+ return compoundIsSuperselector(lhs2, rhs2, {});
598
+ }
599
+
600
+ /////////////////////////////////////////////////////////////////////////
601
+ /////////////////////////////////////////////////////////////////////////
602
+
603
+ MediaRule::MediaRule(SourceSpan pstate, Block_Obj block) :
604
+ ParentStatement(pstate, block),
605
+ schema_({})
606
+ {
607
+ statement_type(MEDIA);
608
+ }
609
+
610
+ MediaRule::MediaRule(const MediaRule* ptr) :
611
+ ParentStatement(ptr),
612
+ schema_(ptr->schema_)
613
+ {
614
+ statement_type(MEDIA);
615
+ }
616
+
617
+ /////////////////////////////////////////////////////////////////////////
618
+ /////////////////////////////////////////////////////////////////////////
619
+
620
+ CssMediaRule::CssMediaRule(SourceSpan pstate, Block_Obj block) :
621
+ ParentStatement(pstate, block),
622
+ Vectorized()
623
+ {
624
+ statement_type(MEDIA);
625
+ }
626
+
627
+ CssMediaRule::CssMediaRule(const CssMediaRule* ptr) :
628
+ ParentStatement(ptr),
629
+ Vectorized(*ptr)
630
+ {
631
+ statement_type(MEDIA);
632
+ }
633
+
634
+ CssMediaQuery::CssMediaQuery(SourceSpan pstate) :
635
+ AST_Node(pstate),
636
+ modifier_(""),
637
+ type_(""),
638
+ features_()
639
+ {
640
+ }
641
+
642
+ /////////////////////////////////////////////////////////////////////////
643
+ /////////////////////////////////////////////////////////////////////////
644
+
645
+ bool CssMediaQuery::operator==(const CssMediaQuery& rhs) const
646
+ {
647
+ return type_ == rhs.type_
648
+ && modifier_ == rhs.modifier_
649
+ && features_ == rhs.features_;
650
+ }
651
+
652
+ // Implemented after dart-sass (maybe move to other class?)
653
+ CssMediaQuery_Obj CssMediaQuery::merge(CssMediaQuery_Obj& other)
654
+ {
655
+
656
+ sass::string ourType = this->type();
657
+ Util::ascii_str_tolower(&ourType);
658
+
659
+ sass::string theirType = other->type();
660
+ Util::ascii_str_tolower(&theirType);
661
+
662
+ sass::string ourModifier = this->modifier();
663
+ Util::ascii_str_tolower(&ourModifier);
664
+
665
+ sass::string theirModifier = other->modifier();
666
+ Util::ascii_str_tolower(&theirModifier);
667
+
668
+ sass::string type;
669
+ sass::string modifier;
670
+ sass::vector<sass::string> features;
671
+
672
+ if (ourType.empty() && theirType.empty()) {
673
+ CssMediaQuery_Obj query = SASS_MEMORY_NEW(CssMediaQuery, pstate());
674
+ sass::vector<sass::string> f1(this->features());
675
+ sass::vector<sass::string> f2(other->features());
676
+ features.insert(features.end(), f1.begin(), f1.end());
677
+ features.insert(features.end(), f2.begin(), f2.end());
678
+ query->features(features);
679
+ return query;
680
+ }
681
+
682
+ if ((ourModifier == "not") != (theirModifier == "not")) {
683
+ if (ourType == theirType) {
684
+ sass::vector<sass::string> negativeFeatures =
685
+ ourModifier == "not" ? this->features() : other->features();
686
+ sass::vector<sass::string> positiveFeatures =
687
+ ourModifier == "not" ? other->features() : this->features();
688
+
689
+ // If the negative features are a subset of the positive features, the
690
+ // query is empty. For example, `not screen and (color)` has no
691
+ // intersection with `screen and (color) and (grid)`.
692
+ // However, `not screen and (color)` *does* intersect with `screen and
693
+ // (grid)`, because it means `not (screen and (color))` and so it allows
694
+ // a screen with no color but with a grid.
695
+ if (listIsSubsetOrEqual(negativeFeatures, positiveFeatures)) {
696
+ return SASS_MEMORY_NEW(CssMediaQuery, pstate());
697
+ }
698
+ else {
699
+ return {};
700
+ }
701
+ }
702
+ else if (this->matchesAllTypes() || other->matchesAllTypes()) {
703
+ return {};
704
+ }
705
+
706
+ if (ourModifier == "not") {
707
+ modifier = theirModifier;
708
+ type = theirType;
709
+ features = other->features();
710
+ }
711
+ else {
712
+ modifier = ourModifier;
713
+ type = ourType;
714
+ features = this->features();
715
+ }
716
+ }
717
+ else if (ourModifier == "not") {
718
+ SASS_ASSERT(theirModifier == "not", "modifiers not is sync");
719
+
720
+ // CSS has no way of representing "neither screen nor print".
721
+ if (ourType != theirType) return {};
722
+
723
+ auto moreFeatures = this->features().size() > other->features().size()
724
+ ? this->features()
725
+ : other->features();
726
+ auto fewerFeatures = this->features().size() > other->features().size()
727
+ ? other->features()
728
+ : this->features();
729
+
730
+ // If one set of features is a superset of the other,
731
+ // use those features because they're strictly narrower.
732
+ if (listIsSubsetOrEqual(fewerFeatures, moreFeatures)) {
733
+ modifier = ourModifier; // "not"
734
+ type = ourType;
735
+ features = moreFeatures;
736
+ }
737
+ else {
738
+ // Otherwise, there's no way to
739
+ // represent the intersection.
740
+ return {};
741
+ }
742
+
743
+ }
744
+ else {
745
+ if (this->matchesAllTypes()) {
746
+ modifier = theirModifier;
747
+ // Omit the type if either input query did, since that indicates that they
748
+ // aren't targeting a browser that requires "all and".
749
+ type = (other->matchesAllTypes() && ourType.empty()) ? "" : theirType;
750
+ sass::vector<sass::string> f1(this->features());
751
+ sass::vector<sass::string> f2(other->features());
752
+ features.insert(features.end(), f1.begin(), f1.end());
753
+ features.insert(features.end(), f2.begin(), f2.end());
754
+ }
755
+ else if (other->matchesAllTypes()) {
756
+ modifier = ourModifier;
757
+ type = ourType;
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 (ourType != theirType) {
764
+ return SASS_MEMORY_NEW(CssMediaQuery, pstate());
765
+ }
766
+ else {
767
+ modifier = ourModifier.empty() ? theirModifier : ourModifier;
768
+ type = ourType;
769
+ sass::vector<sass::string> f1(this->features());
770
+ sass::vector<sass::string> f2(other->features());
771
+ features.insert(features.end(), f1.begin(), f1.end());
772
+ features.insert(features.end(), f2.begin(), f2.end());
773
+ }
774
+ }
775
+
776
+ CssMediaQuery_Obj query = SASS_MEMORY_NEW(CssMediaQuery, pstate());
777
+ query->modifier(modifier == ourModifier ? this->modifier() : other->modifier());
778
+ query->type(ourType.empty() ? other->type() : this->type());
779
+ query->features(features);
780
+ return query;
781
+ }
782
+
783
+ CssMediaQuery::CssMediaQuery(const CssMediaQuery* ptr) :
784
+ AST_Node(*ptr),
785
+ modifier_(ptr->modifier_),
786
+ type_(ptr->type_),
787
+ features_(ptr->features_)
788
+ {
789
+ }
790
+
791
+ /////////////////////////////////////////////////////////////////////////
792
+ // ToDo: finalize specificity implementation
793
+ /////////////////////////////////////////////////////////////////////////
794
+
795
+ size_t SelectorList::maxSpecificity() const
796
+ {
797
+ size_t specificity = 0;
798
+ for (auto complex : elements()) {
799
+ specificity = std::max(specificity, complex->maxSpecificity());
800
+ }
801
+ return specificity;
802
+ }
803
+
804
+ size_t SelectorList::minSpecificity() const
805
+ {
806
+ size_t specificity = 0;
807
+ for (auto complex : elements()) {
808
+ specificity = std::min(specificity, complex->minSpecificity());
809
+ }
810
+ return specificity;
811
+ }
812
+
813
+ size_t CompoundSelector::maxSpecificity() const
814
+ {
815
+ size_t specificity = 0;
816
+ for (auto simple : elements()) {
817
+ specificity += simple->maxSpecificity();
818
+ }
819
+ return specificity;
820
+ }
821
+
822
+ size_t CompoundSelector::minSpecificity() const
823
+ {
824
+ size_t specificity = 0;
825
+ for (auto simple : elements()) {
826
+ specificity += simple->minSpecificity();
827
+ }
828
+ return specificity;
829
+ }
830
+
831
+ size_t ComplexSelector::maxSpecificity() const
832
+ {
833
+ size_t specificity = 0;
834
+ for (auto component : elements()) {
835
+ specificity += component->maxSpecificity();
836
+ }
837
+ return specificity;
838
+ }
839
+
840
+ size_t ComplexSelector::minSpecificity() const
841
+ {
842
+ size_t specificity = 0;
843
+ for (auto component : elements()) {
844
+ specificity += component->minSpecificity();
845
+ }
846
+ return specificity;
847
+ }
848
+
849
+ /////////////////////////////////////////////////////////////////////////
850
+ // ToDo: this might be done easier with new selector format
851
+ /////////////////////////////////////////////////////////////////////////
852
+
853
+ sass::vector<ComplexSelectorObj>
854
+ CompoundSelector::resolve_parent_refs(SelectorStack pstack, Backtraces& traces, bool implicit_parent)
855
+ {
856
+
857
+ auto parent = pstack.back();
858
+ sass::vector<ComplexSelectorObj> rv;
859
+
860
+ for (SimpleSelectorObj simple : elements()) {
861
+ if (PseudoSelector * pseudo = Cast<PseudoSelector>(simple)) {
862
+ if (SelectorList* sel = Cast<SelectorList>(pseudo->selector())) {
863
+ if (parent) {
864
+ pseudo->selector(sel->resolve_parent_refs(
865
+ pstack, traces, implicit_parent));
866
+ }
867
+ }
868
+ }
869
+ }
870
+
871
+ // Mix with parents from stack
872
+ if (hasRealParent()) {
873
+
874
+ if (parent.isNull()) {
875
+ return { wrapInComplex() };
876
+ }
877
+ else {
878
+ for (auto complex : parent->elements()) {
879
+ // The parent complex selector has a compound selector
880
+ if (CompoundSelectorObj tail = Cast<CompoundSelector>(complex->last())) {
881
+ // Create a copy to alter it
882
+ complex = SASS_MEMORY_COPY(complex);
883
+ tail = SASS_MEMORY_COPY(tail);
884
+
885
+ // Check if we can merge front with back
886
+ if (length() > 0 && tail->length() > 0) {
887
+ SimpleSelectorObj back = tail->last();
888
+ SimpleSelectorObj front = first();
889
+ auto simple_back = Cast<SimpleSelector>(back);
890
+ auto simple_front = Cast<TypeSelector>(front);
891
+ if (simple_front && simple_back) {
892
+ simple_back = SASS_MEMORY_COPY(simple_back);
893
+ auto name = simple_back->name();
894
+ name += simple_front->name();
895
+ simple_back->name(name);
896
+ tail->elements().back() = simple_back;
897
+ tail->elements().insert(tail->end(),
898
+ begin() + 1, end());
899
+ }
900
+ else {
901
+ tail->concat(this);
902
+ }
903
+ }
904
+ else {
905
+ tail->concat(this);
906
+ }
907
+
908
+ complex->elements().back() = tail;
909
+ // Append to results
910
+ rv.push_back(complex);
911
+ }
912
+ else {
913
+ // Can't insert parent that ends with a combinator
914
+ // where the parent selector is followed by something
915
+ if (parent && length() > 0) {
916
+ throw Exception::InvalidParent(parent, traces, this);
917
+ }
918
+ // Create a copy to alter it
919
+ complex = SASS_MEMORY_COPY(complex);
920
+ // Just append ourself
921
+ complex->append(this);
922
+ // Append to results
923
+ rv.push_back(complex);
924
+ }
925
+ }
926
+ }
927
+ }
928
+
929
+ // No parents
930
+ else {
931
+ // Create a new wrapper to wrap ourself
932
+ auto complex = SASS_MEMORY_NEW(ComplexSelector, pstate());
933
+ // Just append ourself
934
+ complex->append(this);
935
+ // Append to results
936
+ rv.push_back(complex);
937
+ }
938
+
939
+ return rv;
940
+
941
+ }
942
+
943
+ bool cmpSimpleSelectors(SimpleSelector* a, SimpleSelector* b)
944
+ {
945
+ return (a->getSortOrder() < b->getSortOrder());
946
+ }
947
+
948
+ void CompoundSelector::sortChildren()
949
+ {
950
+ std::sort(begin(), end(), cmpSimpleSelectors);
951
+ }
952
+
953
+ /* better return sass::vector? only - is empty container anyway? */
954
+ SelectorList* ComplexSelector::resolve_parent_refs(SelectorStack pstack, Backtraces& traces, bool implicit_parent)
955
+ {
956
+
957
+ sass::vector<sass::vector<ComplexSelectorObj>> vars;
958
+
959
+ auto parent = pstack.back();
960
+
961
+ if (has_real_parent_ref() && !parent) {
962
+ throw Exception::TopLevelParent(traces, pstate());
963
+ }
964
+
965
+ if (!chroots() && parent) {
966
+
967
+ if (!has_real_parent_ref() && !implicit_parent) {
968
+ SelectorList* retval = SASS_MEMORY_NEW(SelectorList, pstate(), 1);
969
+ retval->append(this);
970
+ return retval;
971
+ }
972
+
973
+ vars.push_back(parent->elements());
974
+ }
975
+
976
+ for (auto sel : elements()) {
977
+ if (CompoundSelectorObj comp = Cast<CompoundSelector>(sel)) {
978
+ auto asd = comp->resolve_parent_refs(pstack, traces, implicit_parent);
979
+ if (asd.size() > 0) vars.push_back(asd);
980
+ }
981
+ else {
982
+ // ToDo: merge together sequences whenever possible
983
+ auto cont = SASS_MEMORY_NEW(ComplexSelector, pstate());
984
+ cont->append(sel);
985
+ vars.push_back({ cont });
986
+ }
987
+ }
988
+
989
+ // Need complex selectors to preserve linefeeds
990
+ sass::vector<sass::vector<ComplexSelectorObj>> res = permutateAlt(vars);
991
+
992
+ // std::reverse(std::begin(res), std::end(res));
993
+
994
+ auto lst = SASS_MEMORY_NEW(SelectorList, pstate());
995
+ for (auto items : res) {
996
+ if (items.size() > 0) {
997
+ ComplexSelectorObj first = SASS_MEMORY_COPY(items[0]);
998
+ first->hasPreLineFeed(first->hasPreLineFeed() || (!has_real_parent_ref() && hasPreLineFeed()));
999
+ // ToDo: remove once we know how to handle line feeds
1000
+ // ToDo: currently a mashup between ruby and dart sass
1001
+ // if (has_real_parent_ref()) first->has_line_feed(false);
1002
+ // first->has_line_break(first->has_line_break() || has_line_break());
1003
+ first->chroots(true); // has been resolved by now
1004
+ for (size_t i = 1; i < items.size(); i += 1) {
1005
+ first->concat(items[i]);
1006
+ }
1007
+ lst->append(first);
1008
+ }
1009
+ }
1010
+
1011
+ return lst;
1012
+
1013
+ }
1014
+
1015
+ SelectorList* SelectorList::resolve_parent_refs(SelectorStack pstack, Backtraces& traces, bool implicit_parent)
1016
+ {
1017
+ SelectorList* rv = SASS_MEMORY_NEW(SelectorList, pstate());
1018
+ for (auto sel : elements()) {
1019
+ // Note: this one is tricky as we get back a pointer from resolve parents ...
1020
+ SelectorListObj res = sel->resolve_parent_refs(pstack, traces, implicit_parent);
1021
+ // Note: ... and concat will only append the items in elements
1022
+ // Therefore by passing it directly, the container will leak!
1023
+ rv->concat(res);
1024
+ }
1025
+ return rv;
1026
+ }
1027
+
1028
+ /////////////////////////////////////////////////////////////////////////
1029
+ /////////////////////////////////////////////////////////////////////////
1030
+
1031
+ IMPLEMENT_AST_OPERATORS(Selector_Schema);
1032
+ IMPLEMENT_AST_OPERATORS(PlaceholderSelector);
1033
+ IMPLEMENT_AST_OPERATORS(AttributeSelector);
1034
+ IMPLEMENT_AST_OPERATORS(TypeSelector);
1035
+ IMPLEMENT_AST_OPERATORS(ClassSelector);
1036
+ IMPLEMENT_AST_OPERATORS(IDSelector);
1037
+ IMPLEMENT_AST_OPERATORS(PseudoSelector);
1038
+ IMPLEMENT_AST_OPERATORS(SelectorCombinator);
1039
+ IMPLEMENT_AST_OPERATORS(CompoundSelector);
1040
+ IMPLEMENT_AST_OPERATORS(ComplexSelector);
1041
+ IMPLEMENT_AST_OPERATORS(SelectorList);
1042
+
1043
+ }