sassc 1.7.1 → 1.8.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -1
  3. data/ext/libsass/.gitignore +10 -6
  4. data/ext/libsass/.travis.yml +4 -1
  5. data/ext/libsass/GNUmakefile.am +88 -0
  6. data/ext/libsass/Makefile +157 -76
  7. data/ext/libsass/Makefile.conf +47 -0
  8. data/ext/libsass/Readme.md +13 -14
  9. data/ext/libsass/appveyor.yml +25 -41
  10. data/ext/libsass/configure.ac +20 -7
  11. data/ext/libsass/contrib/plugin.cpp +1 -1
  12. data/ext/libsass/include/sass.h +15 -0
  13. data/ext/libsass/{sass.h → include/sass/base.h} +17 -9
  14. data/ext/libsass/{sass_context.h → include/sass/context.h} +3 -1
  15. data/ext/libsass/{sass_functions.h → include/sass/functions.h} +4 -4
  16. data/ext/libsass/{sass_interface.h → include/sass/interface.h} +5 -2
  17. data/ext/libsass/{sass_values.h → include/sass/values.h} +15 -1
  18. data/ext/libsass/{sass_version.h → include/sass/version.h} +0 -0
  19. data/ext/libsass/{sass_version.h.in → include/sass/version.h.in} +0 -0
  20. data/ext/libsass/{sass2scss.h → include/sass2scss.h} +6 -7
  21. data/ext/libsass/m4/m4-ax_cxx_compile_stdcxx_11.m4 +167 -0
  22. data/ext/libsass/script/ci-build-libsass +67 -23
  23. data/ext/libsass/src/GNUmakefile.am +54 -0
  24. data/ext/libsass/src/ast.cpp +2029 -0
  25. data/ext/libsass/{ast.hpp → src/ast.hpp} +832 -660
  26. data/ext/libsass/src/ast_def_macros.hpp +47 -0
  27. data/ext/libsass/src/ast_factory.hpp +93 -0
  28. data/ext/libsass/{ast_fwd_decl.hpp → src/ast_fwd_decl.hpp} +9 -4
  29. data/ext/libsass/{b64 → src/b64}/cencode.h +1 -1
  30. data/ext/libsass/{b64 → src/b64}/encode.h +0 -0
  31. data/ext/libsass/{backtrace.hpp → src/backtrace.hpp} +9 -10
  32. data/ext/libsass/{base64vlq.cpp → src/base64vlq.cpp} +2 -2
  33. data/ext/libsass/{base64vlq.hpp → src/base64vlq.hpp} +1 -2
  34. data/ext/libsass/{bind.cpp → src/bind.cpp} +96 -59
  35. data/ext/libsass/{bind.hpp → src/bind.hpp} +1 -1
  36. data/ext/libsass/src/c99func.c +54 -0
  37. data/ext/libsass/{cencode.c → src/cencode.c} +5 -5
  38. data/ext/libsass/src/color_maps.cpp +643 -0
  39. data/ext/libsass/src/color_maps.hpp +333 -0
  40. data/ext/libsass/{constants.cpp → src/constants.cpp} +10 -1
  41. data/ext/libsass/{constants.hpp → src/constants.hpp} +7 -0
  42. data/ext/libsass/{context.cpp → src/context.cpp} +152 -122
  43. data/ext/libsass/src/context.hpp +150 -0
  44. data/ext/libsass/{cssize.cpp → src/cssize.cpp} +123 -109
  45. data/ext/libsass/{cssize.hpp → src/cssize.hpp} +9 -13
  46. data/ext/libsass/{debug.hpp → src/debug.hpp} +9 -9
  47. data/ext/libsass/src/debugger.hpp +683 -0
  48. data/ext/libsass/{emitter.cpp → src/emitter.cpp} +13 -13
  49. data/ext/libsass/{emitter.hpp → src/emitter.hpp} +10 -11
  50. data/ext/libsass/src/environment.cpp +184 -0
  51. data/ext/libsass/src/environment.hpp +92 -0
  52. data/ext/libsass/src/error_handling.cpp +46 -0
  53. data/ext/libsass/src/error_handling.hpp +34 -0
  54. data/ext/libsass/src/eval.cpp +1462 -0
  55. data/ext/libsass/src/eval.hpp +107 -0
  56. data/ext/libsass/src/expand.cpp +653 -0
  57. data/ext/libsass/{expand.hpp → src/expand.hpp} +17 -16
  58. data/ext/libsass/{extend.cpp → src/extend.cpp} +198 -139
  59. data/ext/libsass/{extend.hpp → src/extend.hpp} +7 -8
  60. data/ext/libsass/{file.cpp → src/file.cpp} +103 -57
  61. data/ext/libsass/{file.hpp → src/file.hpp} +23 -14
  62. data/ext/libsass/{functions.cpp → src/functions.cpp} +642 -333
  63. data/ext/libsass/{functions.hpp → src/functions.hpp} +17 -4
  64. data/ext/libsass/{inspect.cpp → src/inspect.cpp} +147 -260
  65. data/ext/libsass/{inspect.hpp → src/inspect.hpp} +7 -7
  66. data/ext/libsass/{json.cpp → src/json.cpp} +33 -43
  67. data/ext/libsass/{json.hpp → src/json.hpp} +1 -1
  68. data/ext/libsass/{kwd_arg_macros.hpp → src/kwd_arg_macros.hpp} +0 -0
  69. data/ext/libsass/{lexer.cpp → src/lexer.cpp} +28 -0
  70. data/ext/libsass/{lexer.hpp → src/lexer.hpp} +25 -10
  71. data/ext/libsass/{listize.cpp → src/listize.cpp} +17 -13
  72. data/ext/libsass/{listize.hpp → src/listize.hpp} +0 -2
  73. data/ext/libsass/{mapping.hpp → src/mapping.hpp} +0 -0
  74. data/ext/libsass/src/memory_manager.cpp +76 -0
  75. data/ext/libsass/src/memory_manager.hpp +48 -0
  76. data/ext/libsass/{node.cpp → src/node.cpp} +89 -18
  77. data/ext/libsass/{node.hpp → src/node.hpp} +5 -6
  78. data/ext/libsass/{operation.hpp → src/operation.hpp} +18 -12
  79. data/ext/libsass/{output.cpp → src/output.cpp} +47 -55
  80. data/ext/libsass/{output.hpp → src/output.hpp} +5 -4
  81. data/ext/libsass/src/parser.cpp +2529 -0
  82. data/ext/libsass/{parser.hpp → src/parser.hpp} +84 -60
  83. data/ext/libsass/{paths.hpp → src/paths.hpp} +10 -13
  84. data/ext/libsass/{plugins.cpp → src/plugins.cpp} +14 -17
  85. data/ext/libsass/{plugins.hpp → src/plugins.hpp} +10 -11
  86. data/ext/libsass/{position.cpp → src/position.cpp} +5 -6
  87. data/ext/libsass/{position.hpp → src/position.hpp} +19 -22
  88. data/ext/libsass/{prelexer.cpp → src/prelexer.cpp} +401 -53
  89. data/ext/libsass/{prelexer.hpp → src/prelexer.hpp} +50 -10
  90. data/ext/libsass/{remove_placeholders.cpp → src/remove_placeholders.cpp} +12 -16
  91. data/ext/libsass/{remove_placeholders.hpp → src/remove_placeholders.hpp} +1 -7
  92. data/ext/libsass/{sass.cpp → src/sass.cpp} +3 -5
  93. data/ext/libsass/{sass2scss.cpp → src/sass2scss.cpp} +51 -46
  94. data/ext/libsass/{sass_context.cpp → src/sass_context.cpp} +114 -112
  95. data/ext/libsass/{sass_functions.cpp → src/sass_functions.cpp} +11 -18
  96. data/ext/libsass/{sass_interface.cpp → src/sass_interface.cpp} +44 -81
  97. data/ext/libsass/{sass_util.cpp → src/sass_util.cpp} +26 -8
  98. data/ext/libsass/{sass_util.hpp → src/sass_util.hpp} +14 -18
  99. data/ext/libsass/{sass_values.cpp → src/sass_values.cpp} +91 -20
  100. data/ext/libsass/{source_map.cpp → src/source_map.cpp} +13 -13
  101. data/ext/libsass/{source_map.hpp → src/source_map.hpp} +9 -9
  102. data/ext/libsass/{subset_map.hpp → src/subset_map.hpp} +29 -31
  103. data/ext/libsass/{support → src/support}/libsass.pc.in +0 -0
  104. data/ext/libsass/src/to_c.cpp +73 -0
  105. data/ext/libsass/src/to_c.hpp +41 -0
  106. data/ext/libsass/src/to_string.cpp +47 -0
  107. data/ext/libsass/{to_string.hpp → src/to_string.hpp} +9 -7
  108. data/ext/libsass/src/to_value.cpp +109 -0
  109. data/ext/libsass/src/to_value.hpp +50 -0
  110. data/ext/libsass/{units.cpp → src/units.cpp} +56 -51
  111. data/ext/libsass/{units.hpp → src/units.hpp} +8 -9
  112. data/ext/libsass/{utf8.h → src/utf8.h} +0 -0
  113. data/ext/libsass/{utf8 → src/utf8}/checked.h +0 -0
  114. data/ext/libsass/{utf8 → src/utf8}/core.h +12 -12
  115. data/ext/libsass/{utf8 → src/utf8}/unchecked.h +0 -0
  116. data/ext/libsass/{utf8_string.cpp → src/utf8_string.cpp} +0 -0
  117. data/ext/libsass/{utf8_string.hpp → src/utf8_string.hpp} +6 -6
  118. data/ext/libsass/{util.cpp → src/util.cpp} +144 -86
  119. data/ext/libsass/src/util.hpp +59 -0
  120. data/ext/libsass/src/values.cpp +137 -0
  121. data/ext/libsass/src/values.hpp +12 -0
  122. data/ext/libsass/test/test_node.cpp +33 -33
  123. data/ext/libsass/test/test_paths.cpp +5 -6
  124. data/ext/libsass/test/test_selector_difference.cpp +4 -5
  125. data/ext/libsass/test/test_specificity.cpp +4 -5
  126. data/ext/libsass/test/test_subset_map.cpp +91 -91
  127. data/ext/libsass/test/test_superselector.cpp +11 -11
  128. data/ext/libsass/test/test_unification.cpp +4 -4
  129. data/ext/libsass/win/libsass.targets +101 -0
  130. data/ext/libsass/win/libsass.vcxproj +45 -127
  131. data/ext/libsass/win/libsass.vcxproj.filters +303 -0
  132. data/lib/sassc/import_handler.rb +1 -1
  133. data/lib/sassc/native/native_functions_api.rb +3 -3
  134. data/lib/sassc/version.rb +1 -1
  135. data/test/custom_importer_test.rb +1 -4
  136. data/test/functions_test.rb +3 -2
  137. data/test/native_test.rb +4 -3
  138. metadata +117 -110
  139. data/ext/libsass/Makefile.am +0 -146
  140. data/ext/libsass/ast.cpp +0 -945
  141. data/ext/libsass/ast_def_macros.hpp +0 -21
  142. data/ext/libsass/ast_factory.hpp +0 -92
  143. data/ext/libsass/color_names.hpp +0 -327
  144. data/ext/libsass/context.hpp +0 -157
  145. data/ext/libsass/contextualize.cpp +0 -148
  146. data/ext/libsass/contextualize.hpp +0 -46
  147. data/ext/libsass/contextualize_eval.cpp +0 -93
  148. data/ext/libsass/contextualize_eval.hpp +0 -44
  149. data/ext/libsass/debugger.hpp +0 -558
  150. data/ext/libsass/environment.hpp +0 -163
  151. data/ext/libsass/error_handling.cpp +0 -35
  152. data/ext/libsass/error_handling.hpp +0 -32
  153. data/ext/libsass/eval.cpp +0 -1392
  154. data/ext/libsass/eval.hpp +0 -88
  155. data/ext/libsass/expand.cpp +0 -575
  156. data/ext/libsass/memory_manager.hpp +0 -57
  157. data/ext/libsass/parser.cpp +0 -2403
  158. data/ext/libsass/posix/getopt.c +0 -562
  159. data/ext/libsass/posix/getopt.h +0 -95
  160. data/ext/libsass/to_c.cpp +0 -61
  161. data/ext/libsass/to_c.hpp +0 -44
  162. data/ext/libsass/to_string.cpp +0 -34
  163. data/ext/libsass/util.hpp +0 -54
  164. data/ext/libsass/win/libsass.filters +0 -312
@@ -1,945 +0,0 @@
1
- #include "ast.hpp"
2
- #include "context.hpp"
3
- #include "to_string.hpp"
4
- #include <set>
5
- #include <algorithm>
6
- #include <iostream>
7
-
8
- namespace Sass {
9
- using namespace std;
10
-
11
- static Null sass_null(Sass::Null(ParserState("null")));
12
-
13
- bool Compound_Selector::operator<(const Compound_Selector& rhs) const
14
- {
15
- To_String to_string;
16
- // ugly
17
- return const_cast<Compound_Selector*>(this)->perform(&to_string) <
18
- const_cast<Compound_Selector&>(rhs).perform(&to_string);
19
- }
20
-
21
- bool Complex_Selector::operator<(const Complex_Selector& rhs) const
22
- {
23
- To_String to_string;
24
- return const_cast<Complex_Selector*>(this)->perform(&to_string) <
25
- const_cast<Complex_Selector&>(rhs).perform(&to_string);
26
- }
27
-
28
- bool Complex_Selector::operator==(const Complex_Selector& rhs) const {
29
- // TODO: We have to access the tail directly using tail_ since ADD_PROPERTY doesn't provide a const version.
30
-
31
- const Complex_Selector* pOne = this;
32
- const Complex_Selector* pTwo = &rhs;
33
-
34
- // Consume any empty references at the beginning of the Complex_Selector
35
- if (pOne->combinator() == Complex_Selector::ANCESTOR_OF && pOne->head()->is_empty_reference()) {
36
- pOne = pOne->tail_;
37
- }
38
- if (pTwo->combinator() == Complex_Selector::ANCESTOR_OF && pTwo->head()->is_empty_reference()) {
39
- pTwo = pTwo->tail_;
40
- }
41
-
42
- while (pOne && pTwo) {
43
- if (pOne->combinator() != pTwo->combinator()) {
44
- return false;
45
- }
46
-
47
- if (*(pOne->head()) != *(pTwo->head())) {
48
- return false;
49
- }
50
-
51
- pOne = pOne->tail_;
52
- pTwo = pTwo->tail_;
53
- }
54
-
55
- return pOne == NULL && pTwo == NULL;
56
- }
57
-
58
- Compound_Selector* Compound_Selector::unify_with(Compound_Selector* rhs, Context& ctx)
59
- {
60
- Compound_Selector* unified = rhs;
61
- for (size_t i = 0, L = length(); i < L; ++i)
62
- {
63
- if (!unified) break;
64
- else unified = (*this)[i]->unify_with(unified, ctx);
65
- }
66
- return unified;
67
- }
68
-
69
- bool Simple_Selector::operator==(const Simple_Selector& rhs) const
70
- {
71
- // Compare the string representations for equality.
72
-
73
- // Cast away const here. To_String should take a const object, but it doesn't.
74
- Simple_Selector* pLHS = const_cast<Simple_Selector*>(this);
75
- Simple_Selector* pRHS = const_cast<Simple_Selector*>(&rhs);
76
-
77
- To_String to_string;
78
- return pLHS->perform(&to_string) == pRHS->perform(&to_string);
79
- }
80
-
81
- bool Simple_Selector::operator<(const Simple_Selector& rhs) const {
82
- // Use the string representation for ordering.
83
-
84
- // Cast away const here. To_String should take a const object, but it doesn't.
85
- Simple_Selector* pLHS = const_cast<Simple_Selector*>(this);
86
- Simple_Selector* pRHS = const_cast<Simple_Selector*>(&rhs);
87
-
88
- To_String to_string;
89
- return pLHS->perform(&to_string) < pRHS->perform(&to_string);
90
- }
91
-
92
- Compound_Selector* Simple_Selector::unify_with(Compound_Selector* rhs, Context& ctx)
93
- {
94
- To_String to_string(&ctx);
95
- for (size_t i = 0, L = rhs->length(); i < L; ++i)
96
- { if (perform(&to_string) == (*rhs)[i]->perform(&to_string)) return rhs; }
97
-
98
- // check for pseudo elements because they need to come last
99
- size_t i, L;
100
- bool found = false;
101
- if (typeid(*this) == typeid(Pseudo_Selector) || typeid(*this) == typeid(Wrapped_Selector))
102
- {
103
- for (i = 0, L = rhs->length(); i < L; ++i)
104
- {
105
- if ((typeid(*(*rhs)[i]) == typeid(Pseudo_Selector) || typeid(*(*rhs)[i]) == typeid(Wrapped_Selector)) && (*rhs)[L-1]->is_pseudo_element())
106
- { found = true; break; }
107
- }
108
- }
109
- else
110
- {
111
- for (i = 0, L = rhs->length(); i < L; ++i)
112
- {
113
- if (typeid(*(*rhs)[i]) == typeid(Pseudo_Selector) || typeid(*(*rhs)[i]) == typeid(Wrapped_Selector))
114
- { found = true; break; }
115
- }
116
- }
117
- if (!found)
118
- {
119
- Compound_Selector* cpy = new (ctx.mem) Compound_Selector(*rhs);
120
- (*cpy) << this;
121
- return cpy;
122
- }
123
- Compound_Selector* cpy = new (ctx.mem) Compound_Selector(rhs->pstate());
124
- for (size_t j = 0; j < i; ++j)
125
- { (*cpy) << (*rhs)[j]; }
126
- (*cpy) << this;
127
- for (size_t j = i; j < L; ++j)
128
- { (*cpy) << (*rhs)[j]; }
129
- return cpy;
130
- }
131
-
132
- Compound_Selector* Type_Selector::unify_with(Compound_Selector* rhs, Context& ctx)
133
- {
134
- // TODO: handle namespaces
135
-
136
- // if the rhs is empty, just return a copy of this
137
- if (rhs->length() == 0) {
138
- Compound_Selector* cpy = new (ctx.mem) Compound_Selector(rhs->pstate());
139
- (*cpy) << this;
140
- return cpy;
141
- }
142
-
143
- // if this is a universal selector and rhs is not empty, just return the rhs
144
- if (name() == "*")
145
- { return new (ctx.mem) Compound_Selector(*rhs); }
146
-
147
-
148
- Simple_Selector* rhs_0 = (*rhs)[0];
149
- // otherwise, this is a tag name
150
- if (typeid(*rhs_0) == typeid(Type_Selector))
151
- {
152
- // if rhs is universal, just return this tagname + rhs's qualifiers
153
- if (static_cast<Type_Selector*>(rhs_0)->name() == "*")
154
- {
155
- Compound_Selector* cpy = new (ctx.mem) Compound_Selector(rhs->pstate());
156
- (*cpy) << this;
157
- for (size_t i = 1, L = rhs->length(); i < L; ++i)
158
- { (*cpy) << (*rhs)[i]; }
159
- return cpy;
160
- }
161
- // if rhs is another tag name and it matches this, return rhs
162
- else if (static_cast<Type_Selector*>(rhs_0)->name() == name())
163
- { return new (ctx.mem) Compound_Selector(*rhs); }
164
- // else the tag names don't match; return nil
165
- else
166
- { return 0; }
167
- }
168
- // else it's a tag name and a bunch of qualifiers -- just append them
169
- Compound_Selector* cpy = new (ctx.mem) Compound_Selector(rhs->pstate());
170
- (*cpy) << this;
171
- (*cpy) += rhs;
172
- return cpy;
173
- }
174
-
175
- Compound_Selector* Selector_Qualifier::unify_with(Compound_Selector* rhs, Context& ctx)
176
- {
177
- if (name()[0] == '#')
178
- {
179
- for (size_t i = 0, L = rhs->length(); i < L; ++i)
180
- {
181
- Simple_Selector* rhs_i = (*rhs)[i];
182
- if (typeid(*rhs_i) == typeid(Selector_Qualifier) &&
183
- static_cast<Selector_Qualifier*>(rhs_i)->name()[0] == '#' &&
184
- static_cast<Selector_Qualifier*>(rhs_i)->name() != name())
185
- return 0;
186
- }
187
- }
188
- rhs->has_line_break(has_line_break());
189
- return Simple_Selector::unify_with(rhs, ctx);
190
- }
191
-
192
- Compound_Selector* Pseudo_Selector::unify_with(Compound_Selector* rhs, Context& ctx)
193
- {
194
- if (is_pseudo_element())
195
- {
196
- for (size_t i = 0, L = rhs->length(); i < L; ++i)
197
- {
198
- Simple_Selector* rhs_i = (*rhs)[i];
199
- if (typeid(*rhs_i) == typeid(Pseudo_Selector) &&
200
- static_cast<Pseudo_Selector*>(rhs_i)->is_pseudo_element() &&
201
- static_cast<Pseudo_Selector*>(rhs_i)->name() != name())
202
- { return 0; }
203
- }
204
- }
205
- return Simple_Selector::unify_with(rhs, ctx);
206
- }
207
-
208
- bool Compound_Selector::is_superselector_of(Compound_Selector* rhs)
209
- {
210
- To_String to_string;
211
-
212
- Simple_Selector* lbase = base();
213
- Simple_Selector* rbase = rhs->base();
214
-
215
- // Check if pseudo-elements are the same between the selectors
216
-
217
- set<string> lpsuedoset, rpsuedoset;
218
- for (size_t i = 0, L = length(); i < L; ++i)
219
- {
220
- if ((*this)[i]->is_pseudo_element()) {
221
- string pseudo((*this)[i]->perform(&to_string));
222
- pseudo = pseudo.substr(pseudo.find_first_not_of(":")); // strip off colons to ensure :after matches ::after since ruby sass is forgiving
223
- lpsuedoset.insert(pseudo);
224
- }
225
- }
226
- for (size_t i = 0, L = rhs->length(); i < L; ++i)
227
- {
228
- if ((*rhs)[i]->is_pseudo_element()) {
229
- string pseudo((*rhs)[i]->perform(&to_string));
230
- pseudo = pseudo.substr(pseudo.find_first_not_of(":")); // strip off colons to ensure :after matches ::after since ruby sass is forgiving
231
- rpsuedoset.insert(pseudo);
232
- }
233
- }
234
- if (lpsuedoset != rpsuedoset) {
235
- return false;
236
- }
237
-
238
- // Check the Simple_Selectors
239
-
240
- set<string> lset, rset;
241
-
242
- if (!lbase) // no lbase; just see if the left-hand qualifiers are a subset of the right-hand selector
243
- {
244
- for (size_t i = 0, L = length(); i < L; ++i)
245
- {
246
- Selector* lhs = (*this)[i];
247
- // very special case for wrapped matches selector
248
- if (Wrapped_Selector* wrapped = dynamic_cast<Wrapped_Selector*>(lhs)) {
249
- if (wrapped->name() == ":matches(" || wrapped->name() == ":-moz-any(") {
250
- if (Selector_List* list = dynamic_cast<Selector_List*>(wrapped->selector())) {
251
- if (Compound_Selector* comp = dynamic_cast<Compound_Selector*>(rhs)) {
252
- if (list->is_superselector_of(comp)) return true;
253
- }
254
- }
255
- }
256
- }
257
- // match from here on as strings
258
- lset.insert(lhs->perform(&to_string));
259
- }
260
- for (size_t i = 0, L = rhs->length(); i < L; ++i)
261
- { rset.insert((*rhs)[i]->perform(&to_string)); }
262
- return includes(rset.begin(), rset.end(), lset.begin(), lset.end());
263
- }
264
- else { // there's an lbase
265
- for (size_t i = 1, L = length(); i < L; ++i)
266
- { lset.insert((*this)[i]->perform(&to_string)); }
267
- if (rbase)
268
- {
269
- if (lbase->perform(&to_string) != rbase->perform(&to_string)) // if there's an rbase, make sure they match
270
- { return false; }
271
- else // the bases do match, so compare qualifiers
272
- {
273
- for (size_t i = 1, L = rhs->length(); i < L; ++i)
274
- { rset.insert((*rhs)[i]->perform(&to_string)); }
275
- return includes(rset.begin(), rset.end(), lset.begin(), lset.end());
276
- }
277
- }
278
- }
279
- // catch-all
280
- return false;
281
- }
282
-
283
- bool Compound_Selector::operator==(const Compound_Selector& rhs) const {
284
- To_String to_string;
285
-
286
- // Check if pseudo-elements are the same between the selectors
287
-
288
- set<string> lpsuedoset, rpsuedoset;
289
- for (size_t i = 0, L = length(); i < L; ++i)
290
- {
291
- if ((*this)[i]->is_pseudo_element()) {
292
- string pseudo((*this)[i]->perform(&to_string));
293
- pseudo = pseudo.substr(pseudo.find_first_not_of(":")); // strip off colons to ensure :after matches ::after since ruby sass is forgiving
294
- lpsuedoset.insert(pseudo);
295
- }
296
- }
297
- for (size_t i = 0, L = rhs.length(); i < L; ++i)
298
- {
299
- if (rhs[i]->is_pseudo_element()) {
300
- string pseudo(rhs[i]->perform(&to_string));
301
- pseudo = pseudo.substr(pseudo.find_first_not_of(":")); // strip off colons to ensure :after matches ::after since ruby sass is forgiving
302
- rpsuedoset.insert(pseudo);
303
- }
304
- }
305
- if (lpsuedoset != rpsuedoset) {
306
- return false;
307
- }
308
-
309
- // Check the base
310
-
311
- const Simple_Selector* const lbase = base();
312
- const Simple_Selector* const rbase = rhs.base();
313
-
314
- if ((lbase && !rbase) ||
315
- (!lbase && rbase) ||
316
- ((lbase && rbase) && (*lbase != *rbase))) {
317
- return false;
318
- }
319
-
320
-
321
- // Check the rest of the SimpleSelectors
322
- // Use string representations. We can't create a set of Simple_Selector pointers because std::set == std::set is going to call ==
323
- // on the pointers to determine equality. I don't know of a way to pass in a comparison object. The one you can specify as part of
324
- // the template type is used for ordering, but not equality. We also can't just put in non-pointer Simple_Selectors because the
325
- // class is intended to be subclassed, and we'd get splicing.
326
-
327
- set<string> lset, rset;
328
-
329
- for (size_t i = 0, L = length(); i < L; ++i)
330
- { lset.insert((*this)[i]->perform(&to_string)); }
331
- for (size_t i = 0, L = rhs.length(); i < L; ++i)
332
- { rset.insert(rhs[i]->perform(&to_string)); }
333
-
334
- return lset == rset;
335
- }
336
-
337
- bool Complex_Selector_Pointer_Compare::operator() (const Complex_Selector* const pLeft, const Complex_Selector* const pRight) const {
338
- return *pLeft < *pRight;
339
- }
340
-
341
- bool Complex_Selector::is_superselector_of(Compound_Selector* rhs)
342
- {
343
- return base()->is_superselector_of(rhs);
344
- }
345
-
346
- bool Complex_Selector::is_superselector_of(Complex_Selector* rhs)
347
- {
348
- Complex_Selector* lhs = this;
349
- To_String to_string;
350
- // check for selectors with leading or trailing combinators
351
- if (!lhs->head() || !rhs->head())
352
- { return false; }
353
- Complex_Selector* l_innermost = lhs->innermost();
354
- if (l_innermost->combinator() != Complex_Selector::ANCESTOR_OF && !l_innermost->tail())
355
- { return false; }
356
- Complex_Selector* r_innermost = rhs->innermost();
357
- if (r_innermost->combinator() != Complex_Selector::ANCESTOR_OF && !r_innermost->tail())
358
- { return false; }
359
- // more complex (i.e., longer) selectors are always more specific
360
- size_t l_len = lhs->length(), r_len = rhs->length();
361
- if (l_len > r_len)
362
- { return false; }
363
-
364
- if (l_len == 1)
365
- { return lhs->head()->is_superselector_of(rhs->base()); }
366
-
367
- // we have to look one tail deeper, since we cary the
368
- // combinator around for it (which is important here)
369
- if (rhs->tail() && lhs->tail() && combinator() != Complex_Selector::ANCESTOR_OF) {
370
- Complex_Selector* lhs_tail = lhs->tail();
371
- Complex_Selector* rhs_tail = rhs->tail();
372
- if (lhs_tail->combinator() != rhs_tail->combinator()) return false;
373
- if (!lhs_tail->head()->is_superselector_of(rhs_tail->head())) return false;
374
- }
375
-
376
-
377
- bool found = false;
378
- Complex_Selector* marker = rhs;
379
- for (size_t i = 0, L = rhs->length(); i < L; ++i) {
380
- if (i == L-1)
381
- { return false; }
382
- if (lhs->head()->is_superselector_of(marker->head()))
383
- { found = true; break; }
384
- marker = marker->tail();
385
- }
386
- if (!found)
387
- { return false; }
388
-
389
- /*
390
- Hmm, I hope I have the logic right:
391
-
392
- if lhs has a combinator:
393
- if !(marker has a combinator) return false
394
- if !(lhs.combinator == '~' ? marker.combinator != '>' : lhs.combinator == marker.combinator) return false
395
- return lhs.tail-without-innermost.is_superselector_of(marker.tail-without-innermost)
396
- else if marker has a combinator:
397
- if !(marker.combinator == ">") return false
398
- return lhs.tail.is_superselector_of(marker.tail)
399
- else
400
- return lhs.tail.is_superselector_of(marker.tail)
401
- */
402
- if (lhs->combinator() != Complex_Selector::ANCESTOR_OF)
403
- {
404
- if (marker->combinator() == Complex_Selector::ANCESTOR_OF)
405
- { return false; }
406
- if (!(lhs->combinator() == Complex_Selector::PRECEDES ? marker->combinator() != Complex_Selector::PARENT_OF : lhs->combinator() == marker->combinator()))
407
- { return false; }
408
- return lhs->tail()->is_superselector_of(marker->tail());
409
- }
410
- else if (marker->combinator() != Complex_Selector::ANCESTOR_OF)
411
- {
412
- if (marker->combinator() != Complex_Selector::PARENT_OF)
413
- { return false; }
414
- return lhs->tail()->is_superselector_of(marker->tail());
415
- }
416
- else
417
- {
418
- return lhs->tail()->is_superselector_of(marker->tail());
419
- }
420
- // catch-all
421
- return false;
422
- }
423
-
424
- size_t Complex_Selector::length()
425
- {
426
- // TODO: make this iterative
427
- if (!tail()) return 1;
428
- return 1 + tail()->length();
429
- }
430
-
431
- Compound_Selector* Complex_Selector::base()
432
- {
433
- if (!tail()) return head();
434
- else return tail()->base();
435
- }
436
-
437
- Complex_Selector* Complex_Selector::context(Context& ctx)
438
- {
439
- if (!tail()) return 0;
440
- if (!head()) return tail()->context(ctx);
441
- Complex_Selector* cpy = new (ctx.mem) Complex_Selector(pstate(), combinator(), head(), tail()->context(ctx));
442
- cpy->media_block(media_block());
443
- cpy->last_block(last_block());
444
- return cpy;
445
- }
446
-
447
- Complex_Selector* Complex_Selector::innermost()
448
- {
449
- if (!tail()) return this;
450
- else return tail()->innermost();
451
- }
452
-
453
- Complex_Selector::Combinator Complex_Selector::clear_innermost()
454
- {
455
- Combinator c;
456
- if (!tail() || tail()->length() == 1)
457
- { c = combinator(); combinator(ANCESTOR_OF); tail(0); }
458
- else
459
- { c = tail()->clear_innermost(); }
460
- return c;
461
- }
462
-
463
- void Complex_Selector::set_innermost(Complex_Selector* val, Combinator c)
464
- {
465
- if (!tail())
466
- { tail(val); combinator(c); }
467
- else
468
- { tail()->set_innermost(val, c); }
469
- }
470
-
471
- Complex_Selector* Complex_Selector::clone(Context& ctx) const
472
- {
473
- Complex_Selector* cpy = new (ctx.mem) Complex_Selector(*this);
474
- if (tail()) cpy->tail(tail()->clone(ctx));
475
- return cpy;
476
- }
477
-
478
- Complex_Selector* Complex_Selector::cloneFully(Context& ctx) const
479
- {
480
- Complex_Selector* cpy = new (ctx.mem) Complex_Selector(*this);
481
-
482
- if (head()) {
483
- cpy->head(head()->clone(ctx));
484
- }
485
-
486
- if (tail()) {
487
- cpy->tail(tail()->cloneFully(ctx));
488
- }
489
-
490
- return cpy;
491
- }
492
-
493
- Compound_Selector* Compound_Selector::clone(Context& ctx) const
494
- {
495
- Compound_Selector* cpy = new (ctx.mem) Compound_Selector(*this);
496
- return cpy;
497
- }
498
-
499
-
500
-
501
- /* not used anymore - remove?
502
- Selector_Placeholder* Selector::find_placeholder()
503
- {
504
- return 0;
505
- }*/
506
-
507
- void Selector_List::adjust_after_pushing(Complex_Selector* c)
508
- {
509
- if (c->has_reference()) has_reference(true);
510
- if (c->has_placeholder()) has_placeholder(true);
511
-
512
- #ifdef DEBUG
513
- To_String to_string;
514
- this->mCachedSelector(this->perform(&to_string));
515
- #endif
516
- }
517
-
518
- // it's a superselector if every selector of the right side
519
- // list is a superselector of the given left side selector
520
- bool Complex_Selector::is_superselector_of(Selector_List *sub)
521
- {
522
- // Check every rhs selector against left hand list
523
- for(size_t i = 0, L = sub->length(); i < L; ++i) {
524
- if (!is_superselector_of((*sub)[i])) return false;
525
- }
526
- return true;
527
- }
528
-
529
- // it's a superselector if every selector of the right side
530
- // list is a superselector of the given left side selector
531
- bool Selector_List::is_superselector_of(Selector_List *sub)
532
- {
533
- // Check every rhs selector against left hand list
534
- for(size_t i = 0, L = sub->length(); i < L; ++i) {
535
- if (!is_superselector_of((*sub)[i])) return false;
536
- }
537
- return true;
538
- }
539
-
540
- // it's a superselector if every selector on the right side
541
- // is a superselector of any one of the left side selectors
542
- bool Selector_List::is_superselector_of(Compound_Selector *sub)
543
- {
544
- // Check every lhs selector against right hand
545
- for(size_t i = 0, L = length(); i < L; ++i) {
546
- if ((*this)[i]->is_superselector_of(sub)) return true;
547
- }
548
- return false;
549
- }
550
-
551
- // it's a superselector if every selector on the right side
552
- // is a superselector of any one of the left side selectors
553
- bool Selector_List::is_superselector_of(Complex_Selector *sub)
554
- {
555
- // Check every lhs selector against right hand
556
- for(size_t i = 0, L = length(); i < L; ++i) {
557
- if ((*this)[i]->is_superselector_of(sub)) return true;
558
- }
559
- return false;
560
- }
561
-
562
- /* not used anymore - remove?
563
- Selector_Placeholder* Selector_List::find_placeholder()
564
- {
565
- if (has_placeholder()) {
566
- for (size_t i = 0, L = length(); i < L; ++i) {
567
- if ((*this)[i]->has_placeholder()) return (*this)[i]->find_placeholder();
568
- }
569
- }
570
- return 0;
571
- }*/
572
-
573
- /* not used anymore - remove?
574
- Selector_Placeholder* Complex_Selector::find_placeholder()
575
- {
576
- if (has_placeholder()) {
577
- if (head() && head()->has_placeholder()) return head()->find_placeholder();
578
- else if (tail() && tail()->has_placeholder()) return tail()->find_placeholder();
579
- }
580
- return 0;
581
- }*/
582
-
583
- /* not used anymore - remove?
584
- Selector_Placeholder* Compound_Selector::find_placeholder()
585
- {
586
- if (has_placeholder()) {
587
- for (size_t i = 0, L = length(); i < L; ++i) {
588
- if ((*this)[i]->has_placeholder()) return (*this)[i]->find_placeholder();
589
- }
590
- // return this;
591
- }
592
- return 0;
593
- }*/
594
-
595
- /* not used anymore - remove?
596
- Selector_Placeholder* Selector_Placeholder::find_placeholder()
597
- {
598
- return this;
599
- }*/
600
-
601
- vector<string> Compound_Selector::to_str_vec()
602
- {
603
- To_String to_string;
604
- vector<string> result;
605
- result.reserve(length());
606
- for (size_t i = 0, L = length(); i < L; ++i)
607
- { result.push_back((*this)[i]->perform(&to_string)); }
608
- return result;
609
- }
610
-
611
- Compound_Selector* Compound_Selector::minus(Compound_Selector* rhs, Context& ctx)
612
- {
613
- To_String to_string(&ctx);
614
- Compound_Selector* result = new (ctx.mem) Compound_Selector(pstate());
615
-
616
- // not very efficient because it needs to preserve order
617
- for (size_t i = 0, L = length(); i < L; ++i)
618
- {
619
- bool found = false;
620
- string thisSelector((*this)[i]->perform(&to_string));
621
- for (size_t j = 0, M = rhs->length(); j < M; ++j)
622
- {
623
- if (thisSelector == (*rhs)[j]->perform(&to_string))
624
- {
625
- found = true;
626
- break;
627
- }
628
- }
629
- if (!found) (*result) << (*this)[i];
630
- }
631
-
632
- return result;
633
- }
634
-
635
- void Compound_Selector::mergeSources(SourcesSet& sources, Context& ctx)
636
- {
637
- for (SourcesSet::iterator iterator = sources.begin(), endIterator = sources.end(); iterator != endIterator; ++iterator) {
638
- this->sources_.insert((*iterator)->clone(ctx));
639
- }
640
- }
641
-
642
- /* not used anymore - remove?
643
- vector<Compound_Selector*> Complex_Selector::to_vector()
644
- {
645
- vector<Compound_Selector*> result;
646
- Compound_Selector* h = head();
647
- Complex_Selector* t = tail();
648
- if (h) result.push_back(h);
649
- while (t)
650
- {
651
- h = t->head();
652
- t = t->tail();
653
- if (h) result.push_back(h);
654
- }
655
- return result;
656
- }*/
657
-
658
- Number::Number(ParserState pstate, double val, string u, bool zero)
659
- : Expression(pstate),
660
- value_(val),
661
- zero_(zero),
662
- numerator_units_(vector<string>()),
663
- denominator_units_(vector<string>()),
664
- hash_(0)
665
- {
666
- size_t l = 0, r = 0;
667
- if (!u.empty()) {
668
- bool nominator = true;
669
- while (true) {
670
- r = u.find_first_of("*/", l);
671
- string unit(u.substr(l, r - l));
672
- if (nominator) numerator_units_.push_back(unit);
673
- else denominator_units_.push_back(unit);
674
- if (u[r] == '/') nominator = false;
675
- if (r == string::npos) break;
676
- else l = r + 1;
677
- }
678
- }
679
- concrete_type(NUMBER);
680
- }
681
-
682
- string Number::unit() const
683
- {
684
- stringstream u;
685
- for (size_t i = 0, S = numerator_units_.size(); i < S; ++i) {
686
- if (i) u << '*';
687
- u << numerator_units_[i];
688
- }
689
- if (!denominator_units_.empty()) u << '/';
690
- for (size_t i = 0, S = denominator_units_.size(); i < S; ++i) {
691
- if (i) u << '*';
692
- u << denominator_units_[i];
693
- }
694
- return u.str();
695
- }
696
-
697
- bool Number::is_unitless()
698
- { return numerator_units_.empty() && denominator_units_.empty(); }
699
-
700
- void Number::normalize(const string& prefered)
701
- {
702
-
703
- // first make sure same units cancel each other out
704
- // it seems that a map table will fit nicely to do this
705
- // we basically construct exponents for each unit
706
- // has the advantage that they will be pre-sorted
707
- map<string, int> exponents;
708
-
709
- // initialize by summing up occurences in unit vectors
710
- for (size_t i = 0, S = numerator_units_.size(); i < S; ++i) ++ exponents[numerator_units_[i]];
711
- for (size_t i = 0, S = denominator_units_.size(); i < S; ++i) -- exponents[denominator_units_[i]];
712
-
713
- // the final conversion factor
714
- double factor = 1;
715
-
716
- // get the first entry of numerators
717
- // forward it when entry is converted
718
- vector<string>::iterator nom_it = numerator_units_.begin();
719
- vector<string>::iterator nom_end = numerator_units_.end();
720
- vector<string>::iterator denom_it = denominator_units_.begin();
721
- vector<string>::iterator denom_end = denominator_units_.end();
722
-
723
- // main normalization loop
724
- // should be close to optimal
725
- while (denom_it != denom_end)
726
- {
727
- // get and increment afterwards
728
- const string denom = *(denom_it ++);
729
- // skip already canceled out unit
730
- if (exponents[denom] >= 0) continue;
731
- // skip all units we don't know how to convert
732
- if (string_to_unit(denom) == UNKNOWN) continue;
733
- // now search for nominator
734
- while (nom_it != nom_end)
735
- {
736
- // get and increment afterwards
737
- const string nom = *(nom_it ++);
738
- // skip already canceled out unit
739
- if (exponents[nom] <= 0) continue;
740
- // skip all units we don't know how to convert
741
- if (string_to_unit(nom) == UNKNOWN) continue;
742
- // we now have two convertable units
743
- // add factor for current conversion
744
- factor *= conversion_factor(nom, denom);
745
- // update nominator/denominator exponent
746
- -- exponents[nom]; ++ exponents[denom];
747
- // inner loop done
748
- break;
749
- }
750
- }
751
-
752
- // now we can build up the new unit arrays
753
- numerator_units_.clear();
754
- denominator_units_.clear();
755
-
756
- // build them by iterating over the exponents
757
- for (auto exp : exponents)
758
- {
759
- // maybe there is more effecient way to push
760
- // the same item multiple times to a vector?
761
- for(size_t i = 0, S = abs(exp.second); i < S; ++i)
762
- {
763
- // opted to have these switches in the inner loop
764
- // makes it more readable and should not cost much
765
- if (exp.second < 0) denominator_units_.push_back(exp.first);
766
- else if (exp.second > 0) numerator_units_.push_back(exp.first);
767
- }
768
- }
769
-
770
- // apply factor to value_
771
- // best precision this way
772
- value_ *= factor;
773
-
774
- // maybe convert to other unit
775
- // easier implemented on its own
776
- try { convert(prefered); }
777
- catch (incompatibleUnits& err)
778
- { error(err.what(), pstate()); }
779
- catch (...) { throw; }
780
-
781
- }
782
-
783
- void Number::convert(const string& prefered)
784
- {
785
- // abort if unit is empty
786
- if (prefered.empty()) return;
787
-
788
- // first make sure same units cancel each other out
789
- // it seems that a map table will fit nicely to do this
790
- // we basically construct exponents for each unit
791
- // has the advantage that they will be pre-sorted
792
- map<string, int> exponents;
793
-
794
- // initialize by summing up occurences in unit vectors
795
- for (size_t i = 0, S = numerator_units_.size(); i < S; ++i) ++ exponents[numerator_units_[i]];
796
- for (size_t i = 0, S = denominator_units_.size(); i < S; ++i) -- exponents[denominator_units_[i]];
797
-
798
- // the final conversion factor
799
- double factor = 1;
800
-
801
- vector<string>::iterator denom_it = denominator_units_.begin();
802
- vector<string>::iterator denom_end = denominator_units_.end();
803
-
804
- // main normalization loop
805
- // should be close to optimal
806
- while (denom_it != denom_end)
807
- {
808
- // get and increment afterwards
809
- const string denom = *(denom_it ++);
810
- // check if conversion is needed
811
- if (denom == prefered) continue;
812
- // skip already canceled out unit
813
- if (exponents[denom] >= 0) continue;
814
- // skip all units we don't know how to convert
815
- if (string_to_unit(denom) == UNKNOWN) continue;
816
- // we now have two convertable units
817
- // add factor for current conversion
818
- factor *= conversion_factor(denom, prefered);
819
- // update nominator/denominator exponent
820
- ++ exponents[denom]; -- exponents[prefered];
821
- }
822
-
823
- vector<string>::iterator nom_it = numerator_units_.begin();
824
- vector<string>::iterator nom_end = numerator_units_.end();
825
-
826
- // now search for nominator
827
- while (nom_it != nom_end)
828
- {
829
- // get and increment afterwards
830
- const string nom = *(nom_it ++);
831
- // check if conversion is needed
832
- if (nom == prefered) continue;
833
- // skip already canceled out unit
834
- if (exponents[nom] <= 0) continue;
835
- // skip all units we don't know how to convert
836
- if (string_to_unit(nom) == UNKNOWN) continue;
837
- // we now have two convertable units
838
- // add factor for current conversion
839
- factor *= conversion_factor(nom, prefered);
840
- // update nominator/denominator exponent
841
- -- exponents[nom]; ++ exponents[prefered];
842
- }
843
-
844
- // now we can build up the new unit arrays
845
- numerator_units_.clear();
846
- denominator_units_.clear();
847
-
848
- // build them by iterating over the exponents
849
- for (auto exp : exponents)
850
- {
851
- // maybe there is more effecient way to push
852
- // the same item multiple times to a vector?
853
- for(size_t i = 0, S = abs(exp.second); i < S; ++i)
854
- {
855
- // opted to have these switches in the inner loop
856
- // makes it more readable and should not cost much
857
- if (exp.second < 0) denominator_units_.push_back(exp.first);
858
- else if (exp.second > 0) numerator_units_.push_back(exp.first);
859
- }
860
- }
861
-
862
- // apply factor to value_
863
- // best precision this way
864
- value_ *= factor;
865
-
866
- }
867
-
868
- // useful for making one number compatible with another
869
- string Number::find_convertible_unit() const
870
- {
871
- for (size_t i = 0, S = numerator_units_.size(); i < S; ++i) {
872
- string u(numerator_units_[i]);
873
- if (string_to_unit(u) != UNKNOWN) return u;
874
- }
875
- for (size_t i = 0, S = denominator_units_.size(); i < S; ++i) {
876
- string u(denominator_units_[i]);
877
- if (string_to_unit(u) != UNKNOWN) return u;
878
- }
879
- return string();
880
- }
881
-
882
-
883
- bool Number::operator== (Expression* rhs) const
884
- {
885
- try
886
- {
887
- Number l(pstate_, value_, unit());
888
- Number& r = dynamic_cast<Number&>(*rhs);
889
- l.normalize(find_convertible_unit());
890
- r.normalize(find_convertible_unit());
891
- return l.unit() == r.unit() &&
892
- l.value() == r.value();
893
- }
894
- catch (std::bad_cast&) {}
895
- catch (...) { throw; }
896
- return false;
897
- }
898
-
899
- bool Number::operator== (Expression& rhs) const
900
- {
901
- return operator==(&rhs);
902
- }
903
-
904
- bool List::operator==(Expression* rhs) const
905
- {
906
- try
907
- {
908
- List* r = dynamic_cast<List*>(rhs);
909
- if (!r || length() != r->length()) return false;
910
- if (separator() != r->separator()) return false;
911
- for (size_t i = 0, L = r->length(); i < L; ++i)
912
- if (*elements()[i] != *(*r)[i]) return false;
913
- return true;
914
- }
915
- catch (std::bad_cast&) {}
916
- catch (...) { throw; }
917
- return false;
918
- }
919
-
920
- bool List::operator== (Expression& rhs) const
921
- {
922
- return operator==(&rhs);
923
- }
924
-
925
- size_t List::size() const {
926
- if (!is_arglist_) return length();
927
- // arglist expects a list of arguments
928
- // so we need to break before keywords
929
- for (size_t i = 0, L = length(); i < L; ++i) {
930
- if (Argument* arg = dynamic_cast<Argument*>((*this)[i])) {
931
- if (!arg->name().empty()) return i;
932
- }
933
- }
934
- return length();
935
- }
936
-
937
- Expression* Hashed::at(Expression* k) const
938
- {
939
- if (elements_.count(k))
940
- { return elements_.at(k); }
941
- else { return &sass_null; }
942
- }
943
-
944
- }
945
-