sassc 1.11.1 → 1.11.2
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.
- checksums.yaml +4 -4
- data/.travis.yml +2 -2
- data/README.md +3 -2
- data/ext/libsass/Makefile.conf +2 -1
- data/ext/libsass/appveyor.yml +10 -5
- data/ext/libsass/docs/dev-ast-memory.md +223 -0
- data/ext/libsass/include/sass/base.h +2 -0
- data/ext/libsass/script/bootstrap +7 -4
- data/ext/libsass/script/ci-build-libsass +3 -3
- data/ext/libsass/script/ci-install-compiler +2 -0
- data/ext/libsass/script/ci-report-coverage +2 -1
- data/ext/libsass/script/test-leaks.pl +103 -0
- data/ext/libsass/src/ast.cpp +621 -495
- data/ext/libsass/src/ast.hpp +801 -367
- data/ext/libsass/src/ast_def_macros.hpp +5 -5
- data/ext/libsass/src/ast_fwd_decl.hpp +312 -14
- data/ext/libsass/src/bind.cpp +54 -51
- data/ext/libsass/src/bind.hpp +3 -7
- data/ext/libsass/src/check_nesting.cpp +117 -120
- data/ext/libsass/src/check_nesting.hpp +38 -34
- data/ext/libsass/src/color_maps.cpp +3 -3
- data/ext/libsass/src/color_maps.hpp +3 -3
- data/ext/libsass/src/context.cpp +33 -34
- data/ext/libsass/src/context.hpp +12 -14
- data/ext/libsass/src/cssize.cpp +200 -228
- data/ext/libsass/src/cssize.hpp +49 -49
- data/ext/libsass/src/debugger.hpp +260 -241
- data/ext/libsass/src/emitter.cpp +6 -6
- data/ext/libsass/src/emitter.hpp +7 -7
- data/ext/libsass/src/environment.cpp +2 -2
- data/ext/libsass/src/environment.hpp +0 -2
- data/ext/libsass/src/error_handling.cpp +5 -5
- data/ext/libsass/src/error_handling.hpp +12 -12
- data/ext/libsass/src/eval.cpp +412 -401
- data/ext/libsass/src/eval.hpp +61 -62
- data/ext/libsass/src/expand.cpp +223 -204
- data/ext/libsass/src/expand.hpp +42 -42
- data/ext/libsass/src/extend.cpp +198 -201
- data/ext/libsass/src/extend.hpp +12 -14
- data/ext/libsass/src/file.hpp +4 -5
- data/ext/libsass/src/functions.cpp +413 -418
- data/ext/libsass/src/functions.hpp +7 -10
- data/ext/libsass/src/inspect.cpp +115 -109
- data/ext/libsass/src/inspect.hpp +69 -69
- data/ext/libsass/src/listize.cpp +31 -33
- data/ext/libsass/src/listize.hpp +8 -10
- data/ext/libsass/src/memory/SharedPtr.cpp +116 -0
- data/ext/libsass/src/memory/SharedPtr.hpp +202 -0
- data/ext/libsass/src/node.cpp +45 -43
- data/ext/libsass/src/node.hpp +15 -15
- data/ext/libsass/src/operation.hpp +136 -136
- data/ext/libsass/src/output.cpp +48 -49
- data/ext/libsass/src/output.hpp +14 -14
- data/ext/libsass/src/parser.cpp +530 -554
- data/ext/libsass/src/parser.hpp +91 -96
- data/ext/libsass/src/prelexer.cpp +13 -10
- data/ext/libsass/src/remove_placeholders.cpp +25 -21
- data/ext/libsass/src/remove_placeholders.hpp +7 -7
- data/ext/libsass/src/sass2scss.cpp +2 -1
- data/ext/libsass/src/sass_context.cpp +125 -107
- data/ext/libsass/src/sass_context.hpp +1 -1
- data/ext/libsass/src/sass_util.hpp +5 -5
- data/ext/libsass/src/sass_values.cpp +27 -27
- data/ext/libsass/src/source_map.cpp +2 -2
- data/ext/libsass/src/source_map.hpp +2 -2
- data/ext/libsass/src/subset_map.cpp +57 -0
- data/ext/libsass/src/subset_map.hpp +8 -76
- data/ext/libsass/src/to_c.cpp +13 -13
- data/ext/libsass/src/to_c.hpp +14 -14
- data/ext/libsass/src/to_value.cpp +20 -20
- data/ext/libsass/src/to_value.hpp +20 -21
- data/ext/libsass/src/util.cpp +55 -88
- data/ext/libsass/src/util.hpp +9 -13
- data/ext/libsass/src/values.cpp +27 -26
- data/ext/libsass/src/values.hpp +2 -2
- data/ext/libsass/test/test_subset_map.cpp +69 -69
- data/ext/libsass/win/libsass.targets +3 -2
- data/ext/libsass/win/libsass.vcxproj.filters +9 -6
- data/lib/sassc/version.rb +1 -1
- data/sassc.gemspec +0 -1
- data/test/native_test.rb +1 -1
- metadata +7 -5
- data/ext/libsass/src/ast_factory.hpp +0 -92
- data/ext/libsass/src/memory_manager.cpp +0 -77
- data/ext/libsass/src/memory_manager.hpp +0 -48
data/ext/libsass/src/ast.cpp
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
#include "extend.hpp"
|
6
6
|
#include "emitter.hpp"
|
7
7
|
#include "color_maps.hpp"
|
8
|
+
#include "ast_fwd_decl.hpp"
|
8
9
|
#include <set>
|
9
10
|
#include <iomanip>
|
10
11
|
#include <iostream>
|
@@ -15,17 +16,35 @@
|
|
15
16
|
|
16
17
|
namespace Sass {
|
17
18
|
|
18
|
-
static Null sass_null(
|
19
|
+
static Null sass_null(ParserState("null"));
|
19
20
|
|
20
|
-
bool Supports_Operator::needs_parens(
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
bool Supports_Operator::needs_parens(Supports_Condition_Obj cond) const {
|
22
|
+
if (Supports_Operator_Obj op = SASS_MEMORY_CAST(Supports_Operator, cond)) {
|
23
|
+
return op->operand() != operand();
|
24
|
+
}
|
25
|
+
return SASS_MEMORY_CAST(Supports_Negation, cond) != NULL;
|
26
|
+
}
|
27
|
+
|
28
|
+
bool Supports_Negation::needs_parens(Supports_Condition_Obj cond) const {
|
29
|
+
return SASS_MEMORY_CAST(Supports_Negation, cond) ||
|
30
|
+
SASS_MEMORY_CAST(Supports_Operator, cond);
|
31
|
+
}
|
32
|
+
|
33
|
+
size_t HashExpression::operator() (Expression_Obj ex) const {
|
34
|
+
return ex ? ex->hash() : 0;
|
35
|
+
}
|
36
|
+
|
37
|
+
size_t HashSimpleSelector::operator() (Simple_Selector_Obj ex) const {
|
38
|
+
return ex ? ex->hash() : 0;
|
24
39
|
}
|
25
40
|
|
26
|
-
|
27
|
-
|
28
|
-
|
41
|
+
|
42
|
+
bool CompareExpression::operator()(const Expression_Obj& lhs, const Expression_Obj& rhs) const {
|
43
|
+
return lhs && rhs && lhs->eq(*rhs);
|
44
|
+
}
|
45
|
+
|
46
|
+
bool CompareSimpleSelector::operator()(Simple_Selector_Obj lhs, Simple_Selector_Obj rhs) const {
|
47
|
+
return &lhs && &rhs && *lhs == *rhs;
|
29
48
|
}
|
30
49
|
|
31
50
|
std::string & str_ltrim(std::string & str)
|
@@ -59,13 +78,13 @@ namespace Sass {
|
|
59
78
|
void String_Schema::rtrim()
|
60
79
|
{
|
61
80
|
if (!empty()) {
|
62
|
-
if (
|
81
|
+
if (String_Ptr str = SASS_MEMORY_CAST(String, last())) str->rtrim();
|
63
82
|
}
|
64
83
|
}
|
65
84
|
void String_Schema::ltrim()
|
66
85
|
{
|
67
86
|
if (!empty()) {
|
68
|
-
if (
|
87
|
+
if (String_Ptr str = SASS_MEMORY_CAST(String, first())) str->ltrim();
|
69
88
|
}
|
70
89
|
}
|
71
90
|
void String_Schema::trim()
|
@@ -82,7 +101,7 @@ namespace Sass {
|
|
82
101
|
|
83
102
|
void Arguments::set_delayed(bool delayed)
|
84
103
|
{
|
85
|
-
for (
|
104
|
+
for (Argument_Obj arg : elements()) {
|
86
105
|
if (arg) arg->set_delayed(delayed);
|
87
106
|
}
|
88
107
|
is_delayed(delayed);
|
@@ -92,7 +111,7 @@ namespace Sass {
|
|
92
111
|
bool At_Root_Query::exclude(std::string str)
|
93
112
|
{
|
94
113
|
bool with = feature() && unquote(feature()->to_string()).compare("with") == 0;
|
95
|
-
|
114
|
+
List_Ptr l = static_cast<List_Ptr>(&value());
|
96
115
|
std::string v;
|
97
116
|
|
98
117
|
if (with)
|
@@ -137,13 +156,13 @@ namespace Sass {
|
|
137
156
|
|
138
157
|
|
139
158
|
|
140
|
-
bool
|
159
|
+
bool Compound_Selector::operator< (const Compound_Selector& rhs) const
|
141
160
|
{
|
142
161
|
size_t L = std::min(length(), rhs.length());
|
143
162
|
for (size_t i = 0; i < L; ++i)
|
144
163
|
{
|
145
|
-
|
146
|
-
|
164
|
+
Simple_Selector_Obj l = (*this)[i];
|
165
|
+
Simple_Selector_Obj r = rhs[i];
|
147
166
|
if (!l && !r) return false;
|
148
167
|
else if (!r) return false;
|
149
168
|
else if (!l) return true;
|
@@ -154,56 +173,56 @@ namespace Sass {
|
|
154
173
|
return length() < rhs.length();
|
155
174
|
}
|
156
175
|
|
157
|
-
bool
|
176
|
+
bool Compound_Selector::has_parent_ref()
|
158
177
|
{
|
159
|
-
for (
|
178
|
+
for (Simple_Selector_Obj s : *this) {
|
160
179
|
if (s && s->has_parent_ref()) return true;
|
161
180
|
}
|
162
181
|
return false;
|
163
182
|
}
|
164
183
|
|
165
|
-
bool
|
184
|
+
bool Compound_Selector::has_real_parent_ref()
|
166
185
|
{
|
167
|
-
for (
|
186
|
+
for (Simple_Selector_Obj s : *this) {
|
168
187
|
if (s && s->has_real_parent_ref()) return true;
|
169
188
|
}
|
170
189
|
return false;
|
171
190
|
}
|
172
191
|
|
173
|
-
bool
|
192
|
+
bool Complex_Selector::has_parent_ref()
|
174
193
|
{
|
175
194
|
return (head() && head()->has_parent_ref()) ||
|
176
195
|
(tail() && tail()->has_parent_ref());
|
177
196
|
}
|
178
197
|
|
179
|
-
bool
|
198
|
+
bool Complex_Selector::has_real_parent_ref()
|
180
199
|
{
|
181
200
|
return (head() && head()->has_real_parent_ref()) ||
|
182
201
|
(tail() && tail()->has_real_parent_ref());
|
183
202
|
}
|
184
203
|
|
185
|
-
bool
|
204
|
+
bool Complex_Selector::operator< (const Complex_Selector& rhs) const
|
186
205
|
{
|
187
206
|
// const iterators for tails
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
207
|
+
Complex_Selector_Ptr_Const l = this;
|
208
|
+
Complex_Selector_Ptr_Const r = &rhs;
|
209
|
+
Compound_Selector_Ptr l_h = l ? &l->head() : 0;
|
210
|
+
Compound_Selector_Ptr r_h = r ? &r->head() : 0;
|
192
211
|
// process all tails
|
193
212
|
while (true)
|
194
213
|
{
|
195
214
|
// skip empty ancestor first
|
196
215
|
if (l && l->is_empty_ancestor())
|
197
216
|
{
|
198
|
-
l = l->tail();
|
199
|
-
l_h = l ? l->head() : 0;
|
217
|
+
l = &l->tail();
|
218
|
+
l_h = l ? &l->head() : 0;
|
200
219
|
continue;
|
201
220
|
}
|
202
221
|
// skip empty ancestor first
|
203
222
|
if (r && r->is_empty_ancestor())
|
204
223
|
{
|
205
|
-
r = r->tail();
|
206
|
-
r_h = r ? r->head() : 0;
|
224
|
+
r = &r->tail();
|
225
|
+
r_h = r ? &r->head() : 0;
|
207
226
|
continue;
|
208
227
|
}
|
209
228
|
// check for valid selectors
|
@@ -216,11 +235,11 @@ namespace Sass {
|
|
216
235
|
if (l->combinator() != r->combinator())
|
217
236
|
{ return l->combinator() < r->combinator(); }
|
218
237
|
// advance to next tails
|
219
|
-
l = l->tail();
|
220
|
-
r = r->tail();
|
238
|
+
l = &l->tail();
|
239
|
+
r = &r->tail();
|
221
240
|
// fetch the next headers
|
222
|
-
l_h = l ? l->head() : 0;
|
223
|
-
r_h = r ? r->head() : 0;
|
241
|
+
l_h = l ? &l->head() : 0;
|
242
|
+
r_h = r ? &r->head() : 0;
|
224
243
|
}
|
225
244
|
// one side is null
|
226
245
|
else if (!r_h) return true;
|
@@ -232,11 +251,11 @@ namespace Sass {
|
|
232
251
|
if (l->combinator() != r->combinator())
|
233
252
|
{ return l->combinator() < r->combinator(); }
|
234
253
|
// advance to next tails
|
235
|
-
l = l->tail();
|
236
|
-
r = r->tail();
|
254
|
+
l = &l->tail();
|
255
|
+
r = &r->tail();
|
237
256
|
// fetch the next headers
|
238
|
-
l_h = l ? l->head() : 0;
|
239
|
-
r_h = r ? r->head() : 0;
|
257
|
+
l_h = l ? &l->head() : 0;
|
258
|
+
r_h = r ? &r->head() : 0;
|
240
259
|
}
|
241
260
|
// heads are not equal
|
242
261
|
else return *l_h < *r_h;
|
@@ -244,28 +263,28 @@ namespace Sass {
|
|
244
263
|
return true;
|
245
264
|
}
|
246
265
|
|
247
|
-
bool
|
266
|
+
bool Complex_Selector::operator== (const Complex_Selector& rhs) const
|
248
267
|
{
|
249
268
|
// const iterators for tails
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
269
|
+
Complex_Selector_Ptr_Const l = this;
|
270
|
+
Complex_Selector_Ptr_Const r = &rhs;
|
271
|
+
Compound_Selector_Ptr l_h = l ? &l->head() : 0;
|
272
|
+
Compound_Selector_Ptr r_h = r ? &r->head() : 0;
|
254
273
|
// process all tails
|
255
274
|
while (true)
|
256
275
|
{
|
257
276
|
// skip empty ancestor first
|
258
277
|
if (l && l->is_empty_ancestor())
|
259
278
|
{
|
260
|
-
l = l->tail();
|
261
|
-
l_h = l ? l->head() : 0;
|
279
|
+
l = &l->tail();
|
280
|
+
l_h = l ? &l->head() : 0;
|
262
281
|
continue;
|
263
282
|
}
|
264
283
|
// skip empty ancestor first
|
265
284
|
if (r && r->is_empty_ancestor())
|
266
285
|
{
|
267
|
-
r = r->tail();
|
268
|
-
r_h = r ? r->head() : 0;
|
286
|
+
r = &r->tail();
|
287
|
+
r_h = r ? &r->head() : 0;
|
269
288
|
continue;
|
270
289
|
}
|
271
290
|
// check the pointers
|
@@ -278,27 +297,27 @@ namespace Sass {
|
|
278
297
|
if (l->combinator() != r->combinator())
|
279
298
|
{ return l->combinator() < r->combinator(); }
|
280
299
|
// advance to next tails
|
281
|
-
l = l->tail();
|
282
|
-
r = r->tail();
|
300
|
+
l = &l->tail();
|
301
|
+
r = &r->tail();
|
283
302
|
// fetch the next heads
|
284
|
-
l_h = l ? l->head() : 0;
|
285
|
-
r_h = r ? r->head() : 0;
|
303
|
+
l_h = l ? &l->head() : 0;
|
304
|
+
r_h = r ? &r->head() : 0;
|
286
305
|
}
|
287
|
-
//
|
288
|
-
else if (!r_h)
|
289
|
-
|
290
|
-
|
291
|
-
|
306
|
+
// equals if other head is empty
|
307
|
+
else if ((!l_h && !r_h) ||
|
308
|
+
(!l_h && r_h->empty()) ||
|
309
|
+
(!r_h && l_h->empty()) ||
|
310
|
+
(*l_h == *r_h))
|
292
311
|
{
|
293
312
|
// check combinator after heads
|
294
313
|
if (l->combinator() != r->combinator())
|
295
314
|
{ return l->combinator() == r->combinator(); }
|
296
315
|
// advance to next tails
|
297
|
-
l = l->tail();
|
298
|
-
r = r->tail();
|
316
|
+
l = &l->tail();
|
317
|
+
r = &r->tail();
|
299
318
|
// fetch the next heads
|
300
|
-
l_h = l ? l->head() : 0;
|
301
|
-
r_h = r ? r->head() : 0;
|
319
|
+
l_h = l ? &l->head() : 0;
|
320
|
+
r_h = r ? &r->head() : 0;
|
302
321
|
}
|
303
322
|
// abort
|
304
323
|
else break;
|
@@ -307,66 +326,111 @@ namespace Sass {
|
|
307
326
|
return false;
|
308
327
|
}
|
309
328
|
|
310
|
-
|
329
|
+
Compound_Selector_Ptr Compound_Selector::unify_with(Compound_Selector_Ptr rhs, Context& ctx)
|
311
330
|
{
|
312
|
-
|
331
|
+
if (empty()) return rhs;
|
332
|
+
Compound_Selector_Obj unified = SASS_MEMORY_COPY(rhs);
|
313
333
|
for (size_t i = 0, L = length(); i < L; ++i)
|
314
334
|
{
|
315
|
-
if (
|
316
|
-
unified = (
|
335
|
+
if (unified.isNull()) break;
|
336
|
+
unified = at(i)->unify_with(&unified, ctx);
|
317
337
|
}
|
318
|
-
return unified;
|
338
|
+
return unified.detach();
|
339
|
+
}
|
340
|
+
|
341
|
+
bool Selector::operator== (const Selector& rhs) const
|
342
|
+
{
|
343
|
+
if (Selector_List_Ptr_Const sl = dynamic_cast<Selector_List_Ptr_Const>(this)) return *sl == rhs;
|
344
|
+
if (Simple_Selector_Ptr_Const sp = dynamic_cast<Simple_Selector_Ptr_Const>(this)) return *sp == rhs;
|
345
|
+
throw std::runtime_error("invalid selector base classes to compare");
|
346
|
+
return false;
|
347
|
+
}
|
348
|
+
|
349
|
+
bool Selector::operator< (const Selector& rhs) const
|
350
|
+
{
|
351
|
+
if (Selector_List_Ptr_Const sl = dynamic_cast<Selector_List_Ptr_Const>(this)) return *sl < rhs;
|
352
|
+
if (Simple_Selector_Ptr_Const sp = dynamic_cast<Simple_Selector_Ptr_Const>(this)) return *sp < rhs;
|
353
|
+
throw std::runtime_error("invalid selector base classes to compare");
|
354
|
+
return false;
|
355
|
+
}
|
356
|
+
|
357
|
+
bool Simple_Selector::operator== (const Selector& rhs) const
|
358
|
+
{
|
359
|
+
if (Simple_Selector_Ptr_Const sp = dynamic_cast<Simple_Selector_Ptr_Const>(&rhs)) return *this == *sp;
|
360
|
+
return false;
|
361
|
+
}
|
362
|
+
|
363
|
+
bool Simple_Selector::operator< (const Selector& rhs) const
|
364
|
+
{
|
365
|
+
if (Simple_Selector_Ptr_Const sp = dynamic_cast<Simple_Selector_Ptr_Const>(&rhs)) return *this < *sp;
|
366
|
+
return false;
|
319
367
|
}
|
320
368
|
|
321
369
|
bool Simple_Selector::operator== (const Simple_Selector& rhs) const
|
322
370
|
{
|
323
|
-
|
324
|
-
|
325
|
-
if (
|
326
|
-
|
327
|
-
|
328
|
-
|
371
|
+
Simple_Type type = simple_type();
|
372
|
+
// dynamic cast is a bottleneck - use concrete type as types are final
|
373
|
+
if (type == PSEUDO_SEL /* Pseudo_Selector_Ptr_Const lp = dynamic_cast<Pseudo_Selector_Ptr_Const>(this) */) {
|
374
|
+
return *static_cast<Pseudo_Selector_Ptr_Const>(this) == rhs;
|
375
|
+
}
|
376
|
+
else if (type == WRAPPED_SEL /* Wrapped_Selector_Ptr_Const lw = dynamic_cast<Wrapped_Selector_Ptr_Const>(this) */) {
|
377
|
+
return *static_cast<Wrapped_Selector_Ptr_Const>(this) == rhs;
|
378
|
+
}
|
379
|
+
else if (type == ATTR_SEL /* Attribute_Selector_Ptr_Const la = dynamic_cast<Attribute_Selector_Ptr_Const>(this) */) {
|
380
|
+
return *static_cast<Attribute_Selector_Ptr_Const>(this) == rhs;
|
381
|
+
}
|
382
|
+
else if (name_ == rhs.name_)
|
383
|
+
{ return is_ns_eq(ns_, rhs.ns_); }
|
384
|
+
else return false;
|
329
385
|
}
|
330
386
|
|
331
387
|
bool Simple_Selector::operator< (const Simple_Selector& rhs) const
|
332
388
|
{
|
333
|
-
|
334
|
-
|
335
|
-
if (
|
336
|
-
|
337
|
-
|
338
|
-
|
389
|
+
Simple_Type type = simple_type();
|
390
|
+
// dynamic cast is a bottleneck - use concrete type as types are final
|
391
|
+
if (type == PSEUDO_SEL /* Pseudo_Selector_Ptr_Const lp = dynamic_cast<Pseudo_Selector_Ptr_Const>(this) */) {
|
392
|
+
return *static_cast<Pseudo_Selector_Ptr_Const>(this) < rhs;
|
393
|
+
}
|
394
|
+
else if (type == WRAPPED_SEL /* Wrapped_Selector_Ptr_Const lw = dynamic_cast<Wrapped_Selector_Ptr_Const>(this) */) {
|
395
|
+
return *static_cast<Wrapped_Selector_Ptr_Const>(this) < rhs;
|
396
|
+
}
|
397
|
+
else if (type == ATTR_SEL /* Attribute_Selector_Ptr_Const la = dynamic_cast<Attribute_Selector_Ptr_Const>(this) */) {
|
398
|
+
return *static_cast<Attribute_Selector_Ptr_Const>(this) < rhs;
|
399
|
+
}
|
400
|
+
if (is_ns_eq(ns_, rhs.ns_))
|
401
|
+
{ return name_ < rhs.name_; }
|
402
|
+
return ns_ < rhs.ns_;
|
339
403
|
}
|
340
404
|
|
341
|
-
bool
|
405
|
+
bool Selector_List::operator== (const Selector& rhs) const
|
342
406
|
{
|
343
407
|
// solve the double dispatch problem by using RTTI information via dynamic cast
|
344
|
-
if (
|
345
|
-
else if (
|
346
|
-
else if (
|
408
|
+
if (Selector_List_Ptr_Const ls = dynamic_cast<Selector_List_Ptr_Const>(&rhs)) { return *this == *ls; }
|
409
|
+
else if (Complex_Selector_Ptr_Const ls = dynamic_cast<Complex_Selector_Ptr_Const>(&rhs)) { return *this == *ls; }
|
410
|
+
else if (Compound_Selector_Ptr_Const ls = dynamic_cast<Compound_Selector_Ptr_Const>(&rhs)) { return *this == *ls; }
|
347
411
|
// no compare method
|
348
412
|
return this == &rhs;
|
349
413
|
}
|
350
414
|
|
351
415
|
// Selector lists can be compared to comma lists
|
352
|
-
bool
|
416
|
+
bool Selector_List::operator==(const Expression& rhs) const
|
353
417
|
{
|
354
418
|
// solve the double dispatch problem by using RTTI information via dynamic cast
|
355
|
-
if (
|
356
|
-
if (
|
419
|
+
if (List_Ptr_Const ls = dynamic_cast<List_Ptr_Const>(&rhs)) { return *this == *ls; }
|
420
|
+
if (Selector_Ptr_Const ls = dynamic_cast<Selector_Ptr_Const>(&rhs)) { return *this == *ls; }
|
357
421
|
// compare invalid (maybe we should error?)
|
358
422
|
return false;
|
359
423
|
}
|
360
424
|
|
361
|
-
bool
|
425
|
+
bool Selector_List::operator== (const Selector_List& rhs) const
|
362
426
|
{
|
363
427
|
// for array access
|
364
428
|
size_t i = 0, n = 0;
|
365
429
|
size_t iL = length();
|
366
430
|
size_t nL = rhs.length();
|
367
431
|
// create temporary vectors and sort them
|
368
|
-
std::vector<
|
369
|
-
std::vector<
|
432
|
+
std::vector<Complex_Selector_Obj> l_lst = this->elements();
|
433
|
+
std::vector<Complex_Selector_Obj> r_lst = rhs.elements();
|
370
434
|
std::sort(l_lst.begin(), l_lst.end(), cmp_complex_selector());
|
371
435
|
std::sort(r_lst.begin(), r_lst.end(), cmp_complex_selector());
|
372
436
|
// process loop
|
@@ -376,8 +440,8 @@ namespace Sass {
|
|
376
440
|
if (i == iL) return iL == nL;
|
377
441
|
else if (n == nL) return iL == nL;
|
378
442
|
// the access the vector items
|
379
|
-
|
380
|
-
|
443
|
+
Complex_Selector_Obj l = l_lst[i];
|
444
|
+
Complex_Selector_Obj r = r_lst[n];
|
381
445
|
// skip nulls
|
382
446
|
if (!l) ++i;
|
383
447
|
else if (!r) ++n;
|
@@ -391,10 +455,25 @@ namespace Sass {
|
|
391
455
|
return true;
|
392
456
|
}
|
393
457
|
|
394
|
-
|
458
|
+
bool Selector_List::operator< (const Selector& rhs) const
|
459
|
+
{
|
460
|
+
if (Selector_List_Ptr_Const sp = dynamic_cast<Selector_List_Ptr_Const>(&rhs)) return *this < *sp;
|
461
|
+
return false;
|
462
|
+
}
|
463
|
+
|
464
|
+
bool Selector_List::operator< (const Selector_List& rhs) const
|
465
|
+
{
|
466
|
+
if (this->length() != rhs.length()) return false;
|
467
|
+
for (size_t i = 0; i < rhs.length(); i ++) {
|
468
|
+
if (!(*at(i) < *rhs.at(i))) return false;
|
469
|
+
}
|
470
|
+
return true;
|
471
|
+
}
|
472
|
+
|
473
|
+
Compound_Selector_Ptr Simple_Selector::unify_with(Compound_Selector_Ptr rhs, Context& ctx)
|
395
474
|
{
|
396
475
|
for (size_t i = 0, L = rhs->length(); i < L; ++i)
|
397
|
-
{ if (to_string(ctx.c_options) == (
|
476
|
+
{ if (to_string(ctx.c_options) == rhs->at(i)->to_string(ctx.c_options)) return rhs; }
|
398
477
|
|
399
478
|
// check for pseudo elements because they are always last
|
400
479
|
size_t i, L;
|
@@ -403,7 +482,7 @@ namespace Sass {
|
|
403
482
|
{
|
404
483
|
for (i = 0, L = rhs->length(); i < L; ++i)
|
405
484
|
{
|
406
|
-
if ((
|
485
|
+
if ((SASS_MEMORY_CAST(Pseudo_Selector, (*rhs)[i]) || SASS_MEMORY_CAST(Wrapped_Selector, (*rhs)[i])) && (*rhs)[L-1]->is_pseudo_element())
|
407
486
|
{ found = true; break; }
|
408
487
|
}
|
409
488
|
}
|
@@ -411,26 +490,20 @@ namespace Sass {
|
|
411
490
|
{
|
412
491
|
for (i = 0, L = rhs->length(); i < L; ++i)
|
413
492
|
{
|
414
|
-
if (
|
493
|
+
if (SASS_MEMORY_CAST(Pseudo_Selector, (*rhs)[i]) || SASS_MEMORY_CAST(Wrapped_Selector, (*rhs)[i]))
|
415
494
|
{ found = true; break; }
|
416
495
|
}
|
417
496
|
}
|
418
497
|
if (!found)
|
419
498
|
{
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
for (size_t j = 0; j < i; ++j)
|
426
|
-
{ (*cpy) << (*rhs)[j]; }
|
427
|
-
(*cpy) << this;
|
428
|
-
for (size_t j = i; j < L; ++j)
|
429
|
-
{ (*cpy) << (*rhs)[j]; }
|
430
|
-
return cpy;
|
499
|
+
rhs->append(this);
|
500
|
+
return rhs;
|
501
|
+
}
|
502
|
+
rhs->elements().insert(rhs->elements().begin() + i, this);
|
503
|
+
return rhs;
|
431
504
|
}
|
432
505
|
|
433
|
-
|
506
|
+
Simple_Selector_Ptr Element_Selector::unify_with(Simple_Selector_Ptr rhs, Context& ctx)
|
434
507
|
{
|
435
508
|
// check if ns can be extended
|
436
509
|
// true for no ns or universal
|
@@ -440,63 +513,54 @@ namespace Sass {
|
|
440
513
|
// true for valid ns and universal
|
441
514
|
if (!rhs->is_universal_ns())
|
442
515
|
{
|
443
|
-
// creaty the copy inside (avoid unnecessary copies)
|
444
|
-
Element_Selector* ts = SASS_MEMORY_NEW(ctx.mem, Element_Selector, *this);
|
445
516
|
// overwrite the name if star is given as name
|
446
|
-
if (
|
517
|
+
if (this->name() == "*") { this->name(rhs->name()); }
|
447
518
|
// now overwrite the namespace name and flag
|
448
|
-
|
519
|
+
this->ns(rhs->ns()); this->has_ns(rhs->has_ns());
|
449
520
|
// return copy
|
450
|
-
return
|
521
|
+
return this;
|
451
522
|
}
|
452
523
|
}
|
453
524
|
// namespace may changed, check the name now
|
454
525
|
// overwrite star (but not with another star)
|
455
526
|
if (name() == "*" && rhs->name() != "*")
|
456
527
|
{
|
457
|
-
// creaty the copy inside (avoid unnecessary copies)
|
458
|
-
Element_Selector* ts = SASS_MEMORY_NEW(ctx.mem, Element_Selector, *this);
|
459
528
|
// simply set the new name
|
460
|
-
|
529
|
+
this->name(rhs->name());
|
461
530
|
// return copy
|
462
|
-
return
|
531
|
+
return this;
|
463
532
|
}
|
464
533
|
// return original
|
465
534
|
return this;
|
466
535
|
}
|
467
536
|
|
468
|
-
|
537
|
+
Compound_Selector_Ptr Element_Selector::unify_with(Compound_Selector_Ptr rhs, Context& ctx)
|
469
538
|
{
|
470
539
|
// TODO: handle namespaces
|
471
540
|
|
472
541
|
// if the rhs is empty, just return a copy of this
|
473
542
|
if (rhs->length() == 0) {
|
474
|
-
|
475
|
-
|
476
|
-
return cpy;
|
543
|
+
rhs->append(this);
|
544
|
+
return rhs;
|
477
545
|
}
|
478
546
|
|
479
|
-
|
547
|
+
Simple_Selector_Ptr rhs_0 = &rhs->at(0);
|
480
548
|
// otherwise, this is a tag name
|
481
549
|
if (name() == "*")
|
482
550
|
{
|
483
551
|
if (typeid(*rhs_0) == typeid(Element_Selector))
|
484
552
|
{
|
485
553
|
// if rhs is universal, just return this tagname + rhs's qualifiers
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
return cpy;
|
554
|
+
Element_Selector_Ptr ts = SASS_MEMORY_CAST_PTR(Element_Selector, rhs_0);
|
555
|
+
rhs->at(0) = this->unify_with(ts, ctx);
|
556
|
+
return rhs;
|
490
557
|
}
|
491
|
-
else if (
|
558
|
+
else if (SASS_MEMORY_CAST_PTR(Class_Selector, rhs_0) || SASS_MEMORY_CAST_PTR(Id_Selector, rhs_0)) {
|
492
559
|
// qualifier is `.class`, so we can prefix with `ns|*.class`
|
493
|
-
SimpleSequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, rhs->pstate());
|
494
560
|
if (has_ns() && !rhs_0->has_ns()) {
|
495
|
-
if (ns() != "*") (
|
561
|
+
if (ns() != "*") rhs->elements().insert(rhs->begin(), this);
|
496
562
|
}
|
497
|
-
|
498
|
-
{ (*cpy) << (*rhs)[i]; }
|
499
|
-
return cpy;
|
563
|
+
return rhs;
|
500
564
|
}
|
501
565
|
|
502
566
|
|
@@ -508,48 +572,42 @@ namespace Sass {
|
|
508
572
|
// if rhs is universal, just return this tagname + rhs's qualifiers
|
509
573
|
if (rhs_0->name() != "*" && rhs_0->ns() != "*" && rhs_0->name() != name()) return 0;
|
510
574
|
// otherwise create new compound and unify first simple selector
|
511
|
-
|
512
|
-
|
513
|
-
return copy;
|
575
|
+
rhs->at(0) = this->unify_with(rhs_0, ctx);
|
576
|
+
return rhs;
|
514
577
|
|
515
578
|
}
|
516
579
|
// else it's a tag name and a bunch of qualifiers -- just append them
|
517
|
-
|
518
|
-
|
519
|
-
(*cpy) += rhs;
|
520
|
-
return cpy;
|
580
|
+
if (name() != "*") rhs->elements().insert(rhs->begin(), this);
|
581
|
+
return rhs;
|
521
582
|
}
|
522
583
|
|
523
|
-
|
584
|
+
Compound_Selector_Ptr Class_Selector::unify_with(Compound_Selector_Ptr rhs, Context& ctx)
|
524
585
|
{
|
525
586
|
rhs->has_line_break(has_line_break());
|
526
587
|
return Simple_Selector::unify_with(rhs, ctx);
|
527
588
|
}
|
528
589
|
|
529
|
-
|
590
|
+
Compound_Selector_Ptr Id_Selector::unify_with(Compound_Selector_Ptr rhs, Context& ctx)
|
530
591
|
{
|
531
592
|
for (size_t i = 0, L = rhs->length(); i < L; ++i)
|
532
593
|
{
|
533
|
-
|
534
|
-
|
535
|
-
return 0;
|
594
|
+
if (Id_Selector_Ptr sel = SASS_MEMORY_CAST(Id_Selector, rhs->at(i))) {
|
595
|
+
if (sel->name() != name()) return 0;
|
536
596
|
}
|
537
597
|
}
|
538
598
|
rhs->has_line_break(has_line_break());
|
539
599
|
return Simple_Selector::unify_with(rhs, ctx);
|
540
600
|
}
|
541
601
|
|
542
|
-
|
602
|
+
Compound_Selector_Ptr Pseudo_Selector::unify_with(Compound_Selector_Ptr rhs, Context& ctx)
|
543
603
|
{
|
544
604
|
if (is_pseudo_element())
|
545
605
|
{
|
546
606
|
for (size_t i = 0, L = rhs->length(); i < L; ++i)
|
547
607
|
{
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
static_cast<Pseudo_Selector*>(rhs_i)->name() != name())
|
552
|
-
{ return 0; }
|
608
|
+
if (Pseudo_Selector_Ptr sel = SASS_MEMORY_CAST(Pseudo_Selector, rhs->at(i))) {
|
609
|
+
if (sel->is_pseudo_element() && sel->name() != name()) return 0;
|
610
|
+
}
|
553
611
|
}
|
554
612
|
}
|
555
613
|
return Simple_Selector::unify_with(rhs, ctx);
|
@@ -560,16 +618,23 @@ namespace Sass {
|
|
560
618
|
if (is_ns_eq(ns(), rhs.ns())) {
|
561
619
|
if (name() == rhs.name()) {
|
562
620
|
if (matcher() == rhs.matcher()) {
|
563
|
-
|
621
|
+
bool no_lhs_val = value().isNull();
|
622
|
+
bool no_rhs_val = rhs.value().isNull();
|
623
|
+
if (no_lhs_val && no_rhs_val) {
|
624
|
+
return true;
|
625
|
+
}
|
626
|
+
if (!no_lhs_val && !no_rhs_val) {
|
627
|
+
return *value() < *rhs.value();
|
628
|
+
}
|
564
629
|
} else { return matcher() < rhs.matcher(); }
|
565
630
|
} else { return name() < rhs.name(); }
|
566
631
|
}
|
567
|
-
|
632
|
+
return false;
|
568
633
|
}
|
569
634
|
|
570
635
|
bool Attribute_Selector::operator< (const Simple_Selector& rhs) const
|
571
636
|
{
|
572
|
-
if (
|
637
|
+
if (Attribute_Selector_Ptr_Const w = dynamic_cast<Attribute_Selector_Ptr_Const>(&rhs))
|
573
638
|
{
|
574
639
|
return *this < *w;
|
575
640
|
}
|
@@ -580,14 +645,30 @@ namespace Sass {
|
|
580
645
|
|
581
646
|
bool Attribute_Selector::operator== (const Attribute_Selector& rhs) const
|
582
647
|
{
|
583
|
-
|
584
|
-
|
585
|
-
|
648
|
+
// get optional value state
|
649
|
+
bool no_lhs_val = value().isNull();
|
650
|
+
bool no_rhs_val = rhs.value().isNull();
|
651
|
+
// both are null, therefore equal
|
652
|
+
if (no_lhs_val && no_rhs_val) {
|
653
|
+
return (name() == rhs.name())
|
654
|
+
&& (matcher() == rhs.matcher())
|
655
|
+
&& (is_ns_eq(ns(), rhs.ns()));
|
656
|
+
}
|
657
|
+
// both are defined, evaluate
|
658
|
+
if (no_lhs_val == no_rhs_val) {
|
659
|
+
return (name() == rhs.name())
|
660
|
+
&& (matcher() == rhs.matcher())
|
661
|
+
&& (is_ns_eq(ns(), rhs.ns()))
|
662
|
+
&& (*value() == *rhs.value());
|
663
|
+
}
|
664
|
+
// not equal
|
665
|
+
return false;
|
666
|
+
|
586
667
|
}
|
587
668
|
|
588
669
|
bool Attribute_Selector::operator== (const Simple_Selector& rhs) const
|
589
670
|
{
|
590
|
-
if (
|
671
|
+
if (Attribute_Selector_Ptr_Const w = dynamic_cast<Attribute_Selector_Ptr_Const>(&rhs))
|
591
672
|
{
|
592
673
|
return *this == *w;
|
593
674
|
}
|
@@ -600,8 +681,8 @@ namespace Sass {
|
|
600
681
|
{
|
601
682
|
if (is_ns_eq(ns(), rhs.ns()) && name() == rhs.name())
|
602
683
|
{
|
603
|
-
|
604
|
-
|
684
|
+
String_Obj lhs_ex = expression();
|
685
|
+
String_Obj rhs_ex = rhs.expression();
|
605
686
|
if (rhs_ex && lhs_ex) return *lhs_ex == *rhs_ex;
|
606
687
|
else return lhs_ex == rhs_ex;
|
607
688
|
}
|
@@ -610,7 +691,7 @@ namespace Sass {
|
|
610
691
|
|
611
692
|
bool Pseudo_Selector::operator== (const Simple_Selector& rhs) const
|
612
693
|
{
|
613
|
-
if (
|
694
|
+
if (Pseudo_Selector_Ptr_Const w = dynamic_cast<Pseudo_Selector_Ptr_Const>(&rhs))
|
614
695
|
{
|
615
696
|
return *this == *w;
|
616
697
|
}
|
@@ -622,7 +703,12 @@ namespace Sass {
|
|
622
703
|
bool Pseudo_Selector::operator< (const Pseudo_Selector& rhs) const
|
623
704
|
{
|
624
705
|
if (is_ns_eq(ns(), rhs.ns()) && name() == rhs.name())
|
625
|
-
{
|
706
|
+
{
|
707
|
+
String_Obj lhs_ex = expression();
|
708
|
+
String_Obj rhs_ex = rhs.expression();
|
709
|
+
if (rhs_ex && lhs_ex) return *lhs_ex < *rhs_ex;
|
710
|
+
else return lhs_ex < rhs_ex;
|
711
|
+
}
|
626
712
|
if (is_ns_eq(ns(), rhs.ns()))
|
627
713
|
{ return name() < rhs.name(); }
|
628
714
|
return ns() < rhs.ns();
|
@@ -630,7 +716,7 @@ namespace Sass {
|
|
630
716
|
|
631
717
|
bool Pseudo_Selector::operator< (const Simple_Selector& rhs) const
|
632
718
|
{
|
633
|
-
if (
|
719
|
+
if (Pseudo_Selector_Ptr_Const w = dynamic_cast<Pseudo_Selector_Ptr_Const>(&rhs))
|
634
720
|
{
|
635
721
|
return *this < *w;
|
636
722
|
}
|
@@ -648,7 +734,7 @@ namespace Sass {
|
|
648
734
|
|
649
735
|
bool Wrapped_Selector::operator== (const Simple_Selector& rhs) const
|
650
736
|
{
|
651
|
-
if (
|
737
|
+
if (Wrapped_Selector_Ptr_Const w = dynamic_cast<Wrapped_Selector_Ptr_Const>(&rhs))
|
652
738
|
{
|
653
739
|
return *this == *w;
|
654
740
|
}
|
@@ -668,7 +754,7 @@ namespace Sass {
|
|
668
754
|
|
669
755
|
bool Wrapped_Selector::operator< (const Simple_Selector& rhs) const
|
670
756
|
{
|
671
|
-
if (
|
757
|
+
if (Wrapped_Selector_Ptr_Const w = dynamic_cast<Wrapped_Selector_Ptr_Const>(&rhs))
|
672
758
|
{
|
673
759
|
return *this < *w;
|
674
760
|
}
|
@@ -677,40 +763,40 @@ namespace Sass {
|
|
677
763
|
return ns() < rhs.ns();
|
678
764
|
}
|
679
765
|
|
680
|
-
bool Wrapped_Selector::is_superselector_of(
|
766
|
+
bool Wrapped_Selector::is_superselector_of(Wrapped_Selector_Obj sub)
|
681
767
|
{
|
682
768
|
if (this->name() != sub->name()) return false;
|
683
769
|
if (this->name() == ":current") return false;
|
684
|
-
if (
|
685
|
-
if (
|
770
|
+
if (Selector_List_Obj rhs_list = SASS_MEMORY_CAST(Selector_List, sub->selector())) {
|
771
|
+
if (Selector_List_Obj lhs_list = SASS_MEMORY_CAST(Selector_List, selector())) {
|
686
772
|
return lhs_list->is_superselector_of(rhs_list);
|
687
773
|
}
|
688
|
-
error("is_superselector expected a
|
774
|
+
error("is_superselector expected a Selector_List", sub->pstate());
|
689
775
|
} else {
|
690
|
-
error("is_superselector expected a
|
776
|
+
error("is_superselector expected a Selector_List", sub->pstate());
|
691
777
|
}
|
692
778
|
return false;
|
693
779
|
}
|
694
780
|
|
695
|
-
bool
|
781
|
+
bool Compound_Selector::is_superselector_of(Selector_List_Obj rhs, std::string wrapped)
|
696
782
|
{
|
697
|
-
for (
|
698
|
-
if (is_superselector_of(item, wrapped)) return true;
|
783
|
+
for (Complex_Selector_Obj item : rhs->elements()) {
|
784
|
+
if (is_superselector_of(&item, wrapped)) return true;
|
699
785
|
}
|
700
786
|
return false;
|
701
787
|
}
|
702
788
|
|
703
|
-
bool
|
789
|
+
bool Compound_Selector::is_superselector_of(Complex_Selector_Obj rhs, std::string wrapped)
|
704
790
|
{
|
705
|
-
if (rhs->head()) return is_superselector_of(rhs->head(), wrapped);
|
791
|
+
if (rhs->head()) return is_superselector_of(&rhs->head(), wrapped);
|
706
792
|
return false;
|
707
793
|
}
|
708
794
|
|
709
|
-
bool
|
795
|
+
bool Compound_Selector::is_superselector_of(Compound_Selector_Obj rhs, std::string wrapping)
|
710
796
|
{
|
711
|
-
|
712
|
-
|
713
|
-
|
797
|
+
Compound_Selector_Ptr lhs = this;
|
798
|
+
Simple_Selector_Ptr lbase = lhs->base();
|
799
|
+
Simple_Selector_Ptr rbase = rhs->base();
|
714
800
|
|
715
801
|
// Check if pseudo-elements are the same between the selectors
|
716
802
|
|
@@ -751,11 +837,11 @@ namespace Sass {
|
|
751
837
|
|
752
838
|
for (size_t i = 0, iL = length(); i < iL; ++i)
|
753
839
|
{
|
754
|
-
|
840
|
+
Selector_Obj lhs = &(*this)[i];
|
755
841
|
// very special case for wrapped matches selector
|
756
|
-
if (
|
842
|
+
if (Wrapped_Selector_Obj wrapped = SASS_MEMORY_CAST(Wrapped_Selector, lhs)) {
|
757
843
|
if (wrapped->name() == ":not") {
|
758
|
-
if (
|
844
|
+
if (Selector_List_Obj not_list = SASS_MEMORY_CAST(Selector_List, wrapped->selector())) {
|
759
845
|
if (not_list->is_superselector_of(rhs, wrapped->name())) return false;
|
760
846
|
} else {
|
761
847
|
throw std::runtime_error("wrapped not selector is not a list");
|
@@ -763,8 +849,8 @@ namespace Sass {
|
|
763
849
|
}
|
764
850
|
if (wrapped->name() == ":matches" || wrapped->name() == ":-moz-any") {
|
765
851
|
lhs = wrapped->selector();
|
766
|
-
if (
|
767
|
-
if (
|
852
|
+
if (Selector_List_Obj list = SASS_MEMORY_CAST(Selector_List, wrapped->selector())) {
|
853
|
+
if (Compound_Selector_Obj comp = SASS_MEMORY_CAST(Compound_Selector, rhs)) {
|
768
854
|
if (!wrapping.empty() && wrapping != wrapped->name()) return false;
|
769
855
|
if (wrapping.empty() || wrapping != wrapped->name()) {;
|
770
856
|
if (list->is_superselector_of(comp, wrapped->name())) return true;
|
@@ -772,8 +858,8 @@ namespace Sass {
|
|
772
858
|
}
|
773
859
|
}
|
774
860
|
}
|
775
|
-
|
776
|
-
if (
|
861
|
+
Simple_Selector_Ptr rhs_sel = rhs->elements().size() > i ? &(*rhs)[i] : 0;
|
862
|
+
if (Wrapped_Selector_Ptr wrapped_r = dynamic_cast<Wrapped_Selector_Ptr>(rhs_sel)) {
|
777
863
|
if (wrapped->name() == wrapped_r->name()) {
|
778
864
|
if (wrapped->is_superselector_of(wrapped_r)) {
|
779
865
|
continue;
|
@@ -788,10 +874,10 @@ namespace Sass {
|
|
788
874
|
|
789
875
|
for (size_t n = 0, nL = rhs->length(); n < nL; ++n)
|
790
876
|
{
|
791
|
-
|
792
|
-
if (
|
877
|
+
Selector_Obj r = &(*rhs)[n];
|
878
|
+
if (Wrapped_Selector_Obj wrapped = SASS_MEMORY_CAST(Wrapped_Selector, r)) {
|
793
879
|
if (wrapped->name() == ":not") {
|
794
|
-
if (
|
880
|
+
if (Selector_List_Obj ls = SASS_MEMORY_CAST(Selector_List, wrapped->selector())) {
|
795
881
|
ls->remove_parent_selectors();
|
796
882
|
if (is_superselector_of(ls, wrapped->name())) return false;
|
797
883
|
}
|
@@ -800,7 +886,7 @@ namespace Sass {
|
|
800
886
|
if (!wrapping.empty()) {
|
801
887
|
if (wrapping != wrapped->name()) return false;
|
802
888
|
}
|
803
|
-
if (
|
889
|
+
if (Selector_List_Obj ls = SASS_MEMORY_CAST(Selector_List, wrapped->selector())) {
|
804
890
|
ls->remove_parent_selectors();
|
805
891
|
return (is_superselector_of(ls, wrapped->name()));
|
806
892
|
}
|
@@ -819,22 +905,22 @@ namespace Sass {
|
|
819
905
|
}
|
820
906
|
|
821
907
|
// create complex selector (ancestor of) from compound selector
|
822
|
-
|
908
|
+
Complex_Selector_Obj Compound_Selector::to_complex()
|
823
909
|
{
|
824
910
|
// create an intermediate complex selector
|
825
|
-
return SASS_MEMORY_NEW(
|
911
|
+
return SASS_MEMORY_NEW(Complex_Selector,
|
826
912
|
pstate(),
|
827
|
-
|
913
|
+
Complex_Selector::ANCESTOR_OF,
|
828
914
|
this,
|
829
915
|
0);
|
830
916
|
}
|
831
917
|
|
832
|
-
|
918
|
+
Selector_List_Ptr Complex_Selector::unify_with(Complex_Selector_Ptr other, Context& ctx)
|
833
919
|
{
|
834
920
|
|
835
921
|
// get last tails (on the right side)
|
836
|
-
|
837
|
-
|
922
|
+
Complex_Selector_Obj l_last = this->last();
|
923
|
+
Complex_Selector_Obj r_last = other->last();
|
838
924
|
|
839
925
|
// check valid pointers (assertion)
|
840
926
|
SASS_ASSERT(l_last, "lhs is null");
|
@@ -847,15 +933,15 @@ namespace Sass {
|
|
847
933
|
if (r_last->combinator() != Combinator::ANCESTOR_OF ) return 0;
|
848
934
|
|
849
935
|
// get the headers for the last tails
|
850
|
-
|
851
|
-
|
936
|
+
Compound_Selector_Obj l_last_head = l_last->head();
|
937
|
+
Compound_Selector_Obj r_last_head = r_last->head();
|
852
938
|
|
853
939
|
// check valid head pointers (assertion)
|
854
940
|
SASS_ASSERT(l_last_head, "lhs head is null");
|
855
941
|
SASS_ASSERT(r_last_head, "rhs head is null");
|
856
942
|
|
857
943
|
// get the unification of the last compound selectors
|
858
|
-
|
944
|
+
Compound_Selector_Obj unified = r_last_head->unify_with(&l_last_head, ctx);
|
859
945
|
|
860
946
|
// abort if we could not unify heads
|
861
947
|
if (unified == 0) return 0;
|
@@ -879,33 +965,33 @@ namespace Sass {
|
|
879
965
|
if (!is_universal)
|
880
966
|
{
|
881
967
|
// create some temporaries to convert to node
|
882
|
-
|
883
|
-
Node unified_node = complexSelectorToNode(fake, ctx);
|
968
|
+
Complex_Selector_Obj fake = unified->to_complex();
|
969
|
+
Node unified_node = complexSelectorToNode(&fake, ctx);
|
884
970
|
// add to permutate the list?
|
885
971
|
rhsNode.plus(unified_node);
|
886
972
|
}
|
887
973
|
|
888
974
|
// do some magic we inherit from node and extend
|
889
975
|
Node node = Extend::subweave(lhsNode, rhsNode, ctx);
|
890
|
-
|
976
|
+
Selector_List_Ptr result = SASS_MEMORY_NEW(Selector_List, pstate());
|
891
977
|
NodeDequePtr col = node.collection(); // move from collection to list
|
892
978
|
for (NodeDeque::iterator it = col->begin(), end = col->end(); it != end; it++)
|
893
|
-
{ (
|
979
|
+
{ result->append(nodeToComplexSelector(Node::naiveTrim(*it, ctx), ctx)); }
|
894
980
|
|
895
981
|
// only return if list has some entries
|
896
982
|
return result->length() ? result : 0;
|
897
983
|
|
898
984
|
}
|
899
985
|
|
900
|
-
bool
|
986
|
+
bool Compound_Selector::operator== (const Compound_Selector& rhs) const
|
901
987
|
{
|
902
988
|
// for array access
|
903
989
|
size_t i = 0, n = 0;
|
904
990
|
size_t iL = length();
|
905
991
|
size_t nL = rhs.length();
|
906
992
|
// create temporary vectors and sort them
|
907
|
-
std::vector<
|
908
|
-
std::vector<
|
993
|
+
std::vector<Simple_Selector_Obj> l_lst = this->elements();
|
994
|
+
std::vector<Simple_Selector_Obj> r_lst = rhs.elements();
|
909
995
|
std::sort(l_lst.begin(), l_lst.end(), cmp_simple_selector());
|
910
996
|
std::sort(r_lst.begin(), r_lst.end(), cmp_simple_selector());
|
911
997
|
// process loop
|
@@ -915,8 +1001,8 @@ namespace Sass {
|
|
915
1001
|
if (i == iL) return iL == nL;
|
916
1002
|
else if (n == nL) return iL == nL;
|
917
1003
|
// the access the vector items
|
918
|
-
|
919
|
-
|
1004
|
+
Simple_Selector_Obj l = l_lst[i];
|
1005
|
+
Simple_Selector_Obj r = r_lst[n];
|
920
1006
|
// skip nulls
|
921
1007
|
if (!l) ++i;
|
922
1008
|
if (!r) ++n;
|
@@ -930,26 +1016,26 @@ namespace Sass {
|
|
930
1016
|
return true;
|
931
1017
|
}
|
932
1018
|
|
933
|
-
bool
|
1019
|
+
bool Complex_Selector_Pointer_Compare::operator() (const Complex_Selector_Obj& pLeft, const Complex_Selector_Obj& pRight) const {
|
934
1020
|
return *pLeft < *pRight;
|
935
1021
|
}
|
936
1022
|
|
937
|
-
bool
|
1023
|
+
bool Complex_Selector::is_superselector_of(Compound_Selector_Obj rhs, std::string wrapping)
|
938
1024
|
{
|
939
1025
|
return last()->head() && last()->head()->is_superselector_of(rhs, wrapping);
|
940
1026
|
}
|
941
1027
|
|
942
|
-
bool
|
1028
|
+
bool Complex_Selector::is_superselector_of(Complex_Selector_Obj rhs, std::string wrapping)
|
943
1029
|
{
|
944
|
-
|
1030
|
+
Complex_Selector_Ptr lhs = this;
|
945
1031
|
// check for selectors with leading or trailing combinators
|
946
1032
|
if (!lhs->head() || !rhs->head())
|
947
1033
|
{ return false; }
|
948
|
-
|
949
|
-
if (l_innermost->combinator() !=
|
1034
|
+
Complex_Selector_Obj l_innermost = lhs->innermost();
|
1035
|
+
if (l_innermost->combinator() != Complex_Selector::ANCESTOR_OF)
|
950
1036
|
{ return false; }
|
951
|
-
|
952
|
-
if (r_innermost->combinator() !=
|
1037
|
+
Complex_Selector_Obj r_innermost = rhs->innermost();
|
1038
|
+
if (r_innermost->combinator() != Complex_Selector::ANCESTOR_OF)
|
953
1039
|
{ return false; }
|
954
1040
|
// more complex (i.e., longer) selectors are always more specific
|
955
1041
|
size_t l_len = lhs->length(), r_len = rhs->length();
|
@@ -957,27 +1043,27 @@ namespace Sass {
|
|
957
1043
|
{ return false; }
|
958
1044
|
|
959
1045
|
if (l_len == 1)
|
960
|
-
{ return lhs->head()->is_superselector_of(rhs->last()->head(), wrapping); }
|
1046
|
+
{ return lhs->head()->is_superselector_of(&rhs->last()->head(), wrapping); }
|
961
1047
|
|
962
1048
|
// we have to look one tail deeper, since we cary the
|
963
1049
|
// combinator around for it (which is important here)
|
964
|
-
if (rhs->tail() && lhs->tail() && combinator() !=
|
965
|
-
|
966
|
-
|
1050
|
+
if (rhs->tail() && lhs->tail() && combinator() != Complex_Selector::ANCESTOR_OF) {
|
1051
|
+
Complex_Selector_Obj lhs_tail = lhs->tail();
|
1052
|
+
Complex_Selector_Obj rhs_tail = rhs->tail();
|
967
1053
|
if (lhs_tail->combinator() != rhs_tail->combinator()) return false;
|
968
1054
|
if (lhs_tail->head() && !rhs_tail->head()) return false;
|
969
1055
|
if (!lhs_tail->head() && rhs_tail->head()) return false;
|
970
1056
|
if (lhs_tail->head() && rhs_tail->head()) {
|
971
|
-
if (!lhs_tail->head()->is_superselector_of(rhs_tail->head())) return false;
|
1057
|
+
if (!lhs_tail->head()->is_superselector_of(&rhs_tail->head())) return false;
|
972
1058
|
}
|
973
1059
|
}
|
974
1060
|
|
975
1061
|
bool found = false;
|
976
|
-
|
1062
|
+
Complex_Selector_Obj marker = rhs;
|
977
1063
|
for (size_t i = 0, L = rhs->length(); i < L; ++i) {
|
978
1064
|
if (i == L-1)
|
979
1065
|
{ return false; }
|
980
|
-
if (lhs->head() && marker->head() && lhs->head()->is_superselector_of(marker->head(), wrapping))
|
1066
|
+
if (lhs->head() && marker->head() && lhs->head()->is_superselector_of(&marker->head(), wrapping))
|
981
1067
|
{ found = true; break; }
|
982
1068
|
marker = marker->tail();
|
983
1069
|
}
|
@@ -997,40 +1083,40 @@ namespace Sass {
|
|
997
1083
|
else
|
998
1084
|
return lhs.tail.is_superselector_of(marker.tail)
|
999
1085
|
*/
|
1000
|
-
if (lhs->combinator() !=
|
1086
|
+
if (lhs->combinator() != Complex_Selector::ANCESTOR_OF)
|
1001
1087
|
{
|
1002
|
-
if (marker->combinator() ==
|
1088
|
+
if (marker->combinator() == Complex_Selector::ANCESTOR_OF)
|
1003
1089
|
{ return false; }
|
1004
|
-
if (!(lhs->combinator() ==
|
1090
|
+
if (!(lhs->combinator() == Complex_Selector::PRECEDES ? marker->combinator() != Complex_Selector::PARENT_OF : lhs->combinator() == marker->combinator()))
|
1005
1091
|
{ return false; }
|
1006
|
-
return lhs->tail()->is_superselector_of(marker->tail());
|
1092
|
+
return lhs->tail()->is_superselector_of(&marker->tail());
|
1007
1093
|
}
|
1008
|
-
else if (marker->combinator() !=
|
1094
|
+
else if (marker->combinator() != Complex_Selector::ANCESTOR_OF)
|
1009
1095
|
{
|
1010
|
-
if (marker->combinator() !=
|
1096
|
+
if (marker->combinator() != Complex_Selector::PARENT_OF)
|
1011
1097
|
{ return false; }
|
1012
|
-
return lhs->tail()->is_superselector_of(marker->tail());
|
1098
|
+
return lhs->tail()->is_superselector_of(&marker->tail());
|
1013
1099
|
}
|
1014
1100
|
else
|
1015
1101
|
{
|
1016
|
-
return lhs->tail()->is_superselector_of(marker->tail());
|
1102
|
+
return lhs->tail()->is_superselector_of(&marker->tail());
|
1017
1103
|
}
|
1018
1104
|
// catch-all
|
1019
1105
|
return false;
|
1020
1106
|
}
|
1021
1107
|
|
1022
|
-
size_t
|
1108
|
+
size_t Complex_Selector::length() const
|
1023
1109
|
{
|
1024
1110
|
// TODO: make this iterative
|
1025
1111
|
if (!tail()) return 1;
|
1026
1112
|
return 1 + tail()->length();
|
1027
1113
|
}
|
1028
1114
|
|
1029
|
-
|
1115
|
+
Complex_Selector_Obj Complex_Selector::context(Context& ctx)
|
1030
1116
|
{
|
1031
1117
|
if (!tail()) return 0;
|
1032
1118
|
if (!head()) return tail()->context(ctx);
|
1033
|
-
|
1119
|
+
Complex_Selector_Obj cpy = SASS_MEMORY_NEW(Complex_Selector, pstate(), combinator(), head(), tail()->context(ctx));
|
1034
1120
|
cpy->media_block(media_block());
|
1035
1121
|
return cpy;
|
1036
1122
|
}
|
@@ -1039,13 +1125,13 @@ namespace Sass {
|
|
1039
1125
|
// check if we need to append some headers
|
1040
1126
|
// then we need to check for the combinator
|
1041
1127
|
// only then we can safely set the new tail
|
1042
|
-
void
|
1128
|
+
void Complex_Selector::append(Context& ctx, Complex_Selector_Obj ss)
|
1043
1129
|
{
|
1044
1130
|
|
1045
|
-
|
1131
|
+
Complex_Selector_Obj t = ss->tail();
|
1046
1132
|
Combinator c = ss->combinator();
|
1047
|
-
|
1048
|
-
|
1133
|
+
String_Obj r = ss->reference();
|
1134
|
+
Compound_Selector_Obj h = ss->head();
|
1049
1135
|
|
1050
1136
|
if (ss->has_line_feed()) has_line_feed(true);
|
1051
1137
|
if (ss->has_line_break()) has_line_break(true);
|
@@ -1055,45 +1141,45 @@ namespace Sass {
|
|
1055
1141
|
if (last()->combinator() != ANCESTOR_OF && c != ANCESTOR_OF) {
|
1056
1142
|
error("Invalid parent selector", pstate_);
|
1057
1143
|
} else if (last()->head_ && last()->head_->length()) {
|
1058
|
-
|
1144
|
+
Compound_Selector_Obj rh = last()->head();
|
1059
1145
|
size_t i = 0, L = h->length();
|
1060
|
-
if (
|
1061
|
-
if (
|
1062
|
-
|
1146
|
+
if (SASS_MEMORY_CAST(Element_Selector, h->first())) {
|
1147
|
+
if (Class_Selector_Ptr sq = SASS_MEMORY_CAST(Class_Selector, rh->last())) {
|
1148
|
+
Class_Selector_Ptr sqs = SASS_MEMORY_COPY(sq);
|
1063
1149
|
sqs->name(sqs->name() + (*h)[0]->name());
|
1064
1150
|
sqs->pstate((*h)[0]->pstate());
|
1065
1151
|
(*rh)[rh->length()-1] = sqs;
|
1066
1152
|
rh->pstate(h->pstate());
|
1067
|
-
for (i = 1; i < L; ++i)
|
1068
|
-
} else if (
|
1069
|
-
|
1153
|
+
for (i = 1; i < L; ++i) rh->append(&(*h)[i]);
|
1154
|
+
} else if (Id_Selector_Ptr sq = SASS_MEMORY_CAST(Id_Selector, rh->last())) {
|
1155
|
+
Id_Selector_Ptr sqs = SASS_MEMORY_COPY(sq);
|
1070
1156
|
sqs->name(sqs->name() + (*h)[0]->name());
|
1071
1157
|
sqs->pstate((*h)[0]->pstate());
|
1072
1158
|
(*rh)[rh->length()-1] = sqs;
|
1073
1159
|
rh->pstate(h->pstate());
|
1074
|
-
for (i = 1; i < L; ++i)
|
1075
|
-
} else if (
|
1076
|
-
|
1160
|
+
for (i = 1; i < L; ++i) rh->append(&(*h)[i]);
|
1161
|
+
} else if (Element_Selector_Ptr ts = SASS_MEMORY_CAST(Element_Selector, rh->last())) {
|
1162
|
+
Element_Selector_Ptr tss = SASS_MEMORY_COPY(ts);
|
1077
1163
|
tss->name(tss->name() + (*h)[0]->name());
|
1078
1164
|
tss->pstate((*h)[0]->pstate());
|
1079
1165
|
(*rh)[rh->length()-1] = tss;
|
1080
1166
|
rh->pstate(h->pstate());
|
1081
|
-
for (i = 1; i < L; ++i)
|
1082
|
-
} else if (
|
1083
|
-
|
1167
|
+
for (i = 1; i < L; ++i) rh->append(&(*h)[i]);
|
1168
|
+
} else if (Placeholder_Selector_Ptr ps = SASS_MEMORY_CAST(Placeholder_Selector, rh->last())) {
|
1169
|
+
Placeholder_Selector_Ptr pss = SASS_MEMORY_COPY(ps);
|
1084
1170
|
pss->name(pss->name() + (*h)[0]->name());
|
1085
1171
|
pss->pstate((*h)[0]->pstate());
|
1086
1172
|
(*rh)[rh->length()-1] = pss;
|
1087
1173
|
rh->pstate(h->pstate());
|
1088
|
-
for (i = 1; i < L; ++i)
|
1174
|
+
for (i = 1; i < L; ++i) rh->append(&(*h)[i]);
|
1089
1175
|
} else {
|
1090
|
-
|
1176
|
+
last()->head_->concat(&h);
|
1091
1177
|
}
|
1092
1178
|
} else {
|
1093
|
-
|
1179
|
+
last()->head_->concat(&h);
|
1094
1180
|
}
|
1095
1181
|
} else {
|
1096
|
-
|
1182
|
+
last()->head_->concat(&h);
|
1097
1183
|
}
|
1098
1184
|
} else {
|
1099
1185
|
// std::cerr << "has no or empty head\n";
|
@@ -1101,7 +1187,7 @@ namespace Sass {
|
|
1101
1187
|
|
1102
1188
|
if (last()) {
|
1103
1189
|
if (last()->combinator() != ANCESTOR_OF && c != ANCESTOR_OF) {
|
1104
|
-
|
1190
|
+
Complex_Selector_Ptr inter = SASS_MEMORY_NEW(Complex_Selector, pstate());
|
1105
1191
|
inter->reference(r);
|
1106
1192
|
inter->combinator(c);
|
1107
1193
|
inter->tail(t);
|
@@ -1118,57 +1204,68 @@ namespace Sass {
|
|
1118
1204
|
|
1119
1205
|
}
|
1120
1206
|
|
1121
|
-
|
1207
|
+
Selector_List_Ptr Selector_List::resolve_parent_refs(Context& ctx, std::vector<Selector_List_Obj>& pstack, bool implicit_parent)
|
1122
1208
|
{
|
1123
|
-
if (!this->has_parent_ref()
|
1124
|
-
|
1209
|
+
if (!this->has_parent_ref()) return this;
|
1210
|
+
Selector_List_Ptr ss = SASS_MEMORY_NEW(Selector_List, pstate());
|
1211
|
+
Selector_List_Ptr ps = &pstack.back();
|
1125
1212
|
for (size_t pi = 0, pL = ps->length(); pi < pL; ++pi) {
|
1126
|
-
CommaSequence_Selector* list = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, pstate());
|
1127
|
-
*list << (*ps)[pi];
|
1128
1213
|
for (size_t si = 0, sL = this->length(); si < sL; ++si) {
|
1129
|
-
|
1214
|
+
Selector_List_Obj rv = at(si)->resolve_parent_refs(ctx, pstack, implicit_parent);
|
1215
|
+
ss->concat(&rv);
|
1130
1216
|
}
|
1131
1217
|
}
|
1132
1218
|
return ss;
|
1133
1219
|
}
|
1134
1220
|
|
1135
|
-
|
1221
|
+
Selector_List_Ptr Complex_Selector::resolve_parent_refs(Context& ctx, std::vector<Selector_List_Obj>& pstack, bool implicit_parent)
|
1136
1222
|
{
|
1137
|
-
|
1138
|
-
|
1223
|
+
Complex_Selector_Obj tail = this->tail();
|
1224
|
+
Compound_Selector_Obj head = this->head();
|
1225
|
+
Selector_List_Ptr parents = &pstack.back();
|
1139
1226
|
|
1140
1227
|
if (!this->has_real_parent_ref() && !implicit_parent) {
|
1141
|
-
|
1142
|
-
|
1228
|
+
Selector_List_Ptr retval = SASS_MEMORY_NEW(Selector_List, pstate());
|
1229
|
+
retval->append(this);
|
1143
1230
|
return retval;
|
1144
1231
|
}
|
1145
1232
|
|
1146
1233
|
// first resolve_parent_refs the tail (which may return an expanded list)
|
1147
|
-
|
1234
|
+
Selector_List_Obj tails = tail ? tail->resolve_parent_refs(ctx, pstack, implicit_parent) : 0;
|
1148
1235
|
|
1149
1236
|
if (head && head->length() > 0) {
|
1150
1237
|
|
1151
|
-
|
1238
|
+
Selector_List_Obj retval;
|
1152
1239
|
// we have a parent selector in a simple compound list
|
1153
1240
|
// mix parent complex selector into the compound list
|
1154
|
-
if (
|
1155
|
-
retval = SASS_MEMORY_NEW(
|
1241
|
+
if (SASS_MEMORY_CAST(Parent_Selector, (*head)[0])) {
|
1242
|
+
retval = SASS_MEMORY_NEW(Selector_List, pstate());
|
1243
|
+
|
1244
|
+
// it turns out that real parent references reach
|
1245
|
+
// across @at-root rules, which comes unexpected
|
1246
|
+
if (parents == NULL && head->has_real_parent_ref()) {
|
1247
|
+
int i = pstack.size() - 1;
|
1248
|
+
while (!parents && i > -1) {
|
1249
|
+
parents = &pstack.at(i--);
|
1250
|
+
}
|
1251
|
+
}
|
1252
|
+
|
1156
1253
|
if (parents && parents->length()) {
|
1157
1254
|
if (tails && tails->length() > 0) {
|
1158
1255
|
for (size_t n = 0, nL = tails->length(); n < nL; ++n) {
|
1159
1256
|
for (size_t i = 0, iL = parents->length(); i < iL; ++i) {
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1164
|
-
ss->tail(t ? t
|
1165
|
-
|
1257
|
+
Complex_Selector_Obj t = (*tails)[n];
|
1258
|
+
Complex_Selector_Obj parent = (*parents)[i];
|
1259
|
+
Complex_Selector_Obj s = SASS_MEMORY_CLONE(parent);
|
1260
|
+
Complex_Selector_Obj ss = SASS_MEMORY_CLONE(this);
|
1261
|
+
ss->tail(t ? SASS_MEMORY_CLONE(t) : 0);
|
1262
|
+
Compound_Selector_Obj h = SASS_MEMORY_COPY(head_);
|
1166
1263
|
// remove parent selector from sequence
|
1167
1264
|
if (h->length()) h->erase(h->begin());
|
1168
|
-
ss->head(h->length() ? h : 0);
|
1265
|
+
ss->head(h->length() ? &h : 0);
|
1169
1266
|
// adjust for parent selector (1 char)
|
1170
1267
|
if (h->length()) {
|
1171
|
-
ParserState state((
|
1268
|
+
ParserState state(h->at(0)->pstate());
|
1172
1269
|
state.offset.column += 1;
|
1173
1270
|
state.column -= 1;
|
1174
1271
|
(*h)[0]->pstate(state);
|
@@ -1177,7 +1274,7 @@ namespace Sass {
|
|
1177
1274
|
s->pstate(pstate());
|
1178
1275
|
// append new tail
|
1179
1276
|
s->append(ctx, ss);
|
1180
|
-
|
1277
|
+
retval->append(s);
|
1181
1278
|
}
|
1182
1279
|
}
|
1183
1280
|
}
|
@@ -1185,24 +1282,24 @@ namespace Sass {
|
|
1185
1282
|
// loop above is inside out
|
1186
1283
|
else {
|
1187
1284
|
for (size_t i = 0, iL = parents->length(); i < iL; ++i) {
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1285
|
+
Complex_Selector_Obj parent = (*parents)[i];
|
1286
|
+
Complex_Selector_Obj s = SASS_MEMORY_CLONE(parent);
|
1287
|
+
Complex_Selector_Obj ss = SASS_MEMORY_CLONE(this);
|
1191
1288
|
// this is only if valid if the parent has no trailing op
|
1192
1289
|
// otherwise we cannot append more simple selectors to head
|
1193
1290
|
if (parent->last()->combinator() != ANCESTOR_OF) {
|
1194
|
-
throw Exception::InvalidParent(parent, ss);
|
1291
|
+
throw Exception::InvalidParent(&parent, &ss);
|
1195
1292
|
}
|
1196
|
-
ss->tail(tail ? tail
|
1197
|
-
|
1293
|
+
ss->tail(tail ? SASS_MEMORY_CLONE(tail) : 0);
|
1294
|
+
Compound_Selector_Obj h = SASS_MEMORY_COPY(head_);
|
1198
1295
|
// remove parent selector from sequence
|
1199
1296
|
if (h->length()) h->erase(h->begin());
|
1200
|
-
ss->head(h->length() ? h : 0);
|
1297
|
+
ss->head(h->length() ? &h : 0);
|
1201
1298
|
// \/ IMO ruby sass bug \/
|
1202
1299
|
ss->has_line_feed(false);
|
1203
1300
|
// adjust for parent selector (1 char)
|
1204
1301
|
if (h->length()) {
|
1205
|
-
ParserState state((
|
1302
|
+
ParserState state(h->at(0)->pstate());
|
1206
1303
|
state.offset.column += 1;
|
1207
1304
|
state.column -= 1;
|
1208
1305
|
(*h)[0]->pstate(state);
|
@@ -1210,8 +1307,8 @@ namespace Sass {
|
|
1210
1307
|
// keep old parser state
|
1211
1308
|
s->pstate(pstate());
|
1212
1309
|
// append new tail
|
1213
|
-
s->append(ctx, ss);
|
1214
|
-
|
1310
|
+
s->append(ctx, &ss);
|
1311
|
+
retval->append(s);
|
1215
1312
|
}
|
1216
1313
|
}
|
1217
1314
|
}
|
@@ -1219,129 +1316,97 @@ namespace Sass {
|
|
1219
1316
|
else {
|
1220
1317
|
if (tails && tails->length() > 0) {
|
1221
1318
|
for (size_t n = 0, nL = tails->length(); n < nL; ++n) {
|
1222
|
-
|
1223
|
-
cpy->tail((
|
1224
|
-
cpy->head(SASS_MEMORY_NEW(
|
1319
|
+
Complex_Selector_Obj cpy = SASS_MEMORY_CLONE(this);
|
1320
|
+
cpy->tail(SASS_MEMORY_CLONE(tails->at(n)));
|
1321
|
+
cpy->head(SASS_MEMORY_NEW(Compound_Selector, head->pstate()));
|
1225
1322
|
for (size_t i = 1, L = this->head()->length(); i < L; ++i)
|
1226
|
-
|
1323
|
+
cpy->head()->append(&(*this->head())[i]);
|
1227
1324
|
if (!cpy->head()->length()) cpy->head(0);
|
1228
|
-
|
1325
|
+
retval->append(cpy->skip_empty_reference());
|
1229
1326
|
}
|
1230
1327
|
}
|
1231
1328
|
// have no parent nor tails
|
1232
1329
|
else {
|
1233
|
-
|
1234
|
-
cpy->head(SASS_MEMORY_NEW(
|
1330
|
+
Complex_Selector_Obj cpy = SASS_MEMORY_CLONE(this);
|
1331
|
+
cpy->head(SASS_MEMORY_NEW(Compound_Selector, head->pstate()));
|
1235
1332
|
for (size_t i = 1, L = this->head()->length(); i < L; ++i)
|
1236
|
-
|
1333
|
+
cpy->head()->append(&(*this->head())[i]);
|
1237
1334
|
if (!cpy->head()->length()) cpy->head(0);
|
1238
|
-
|
1335
|
+
retval->append(cpy->skip_empty_reference());
|
1239
1336
|
}
|
1240
1337
|
}
|
1241
1338
|
}
|
1242
1339
|
// no parent selector in head
|
1243
1340
|
else {
|
1244
|
-
retval = this->tails(ctx, tails);
|
1341
|
+
retval = this->tails(ctx, &tails);
|
1245
1342
|
}
|
1246
1343
|
|
1247
|
-
for (
|
1248
|
-
if (
|
1249
|
-
if (
|
1250
|
-
if (parents) ws->selector(sl->resolve_parent_refs(ctx,
|
1344
|
+
for (Simple_Selector_Obj ss : head->elements()) {
|
1345
|
+
if (Wrapped_Selector_Ptr ws = SASS_MEMORY_CAST(Wrapped_Selector, ss)) {
|
1346
|
+
if (Selector_List_Ptr sl = SASS_MEMORY_CAST(Selector_List, ws->selector())) {
|
1347
|
+
if (parents) ws->selector(sl->resolve_parent_refs(ctx, pstack, implicit_parent));
|
1251
1348
|
}
|
1252
1349
|
}
|
1253
1350
|
}
|
1254
1351
|
|
1255
|
-
return retval;
|
1352
|
+
return retval.detach();
|
1256
1353
|
|
1257
1354
|
}
|
1258
1355
|
// has no head
|
1259
1356
|
else {
|
1260
|
-
return this->tails(ctx, tails);
|
1357
|
+
return this->tails(ctx, &tails);
|
1261
1358
|
}
|
1262
1359
|
|
1263
1360
|
// unreachable
|
1264
1361
|
return 0;
|
1265
1362
|
}
|
1266
1363
|
|
1267
|
-
|
1364
|
+
Selector_List_Ptr Complex_Selector::tails(Context& ctx, Selector_List_Ptr tails)
|
1268
1365
|
{
|
1269
|
-
|
1366
|
+
Selector_List_Ptr rv = SASS_MEMORY_NEW(Selector_List, pstate_);
|
1270
1367
|
if (tails && tails->length()) {
|
1271
1368
|
for (size_t i = 0, iL = tails->length(); i < iL; ++i) {
|
1272
|
-
|
1273
|
-
pr->tail((
|
1274
|
-
|
1369
|
+
Complex_Selector_Obj pr = SASS_MEMORY_CLONE(this);
|
1370
|
+
pr->tail(tails->at(i));
|
1371
|
+
rv->append(pr);
|
1275
1372
|
}
|
1276
1373
|
}
|
1277
1374
|
else {
|
1278
|
-
|
1375
|
+
rv->append(this);
|
1279
1376
|
}
|
1280
1377
|
return rv;
|
1281
1378
|
}
|
1282
1379
|
|
1283
1380
|
// return the last tail that is defined
|
1284
|
-
|
1381
|
+
Complex_Selector_Obj Complex_Selector::first()
|
1285
1382
|
{
|
1286
1383
|
// declare variables used in loop
|
1287
|
-
|
1288
|
-
|
1384
|
+
Complex_Selector_Obj cur = this;
|
1385
|
+
Compound_Selector_Obj head;
|
1289
1386
|
// processing loop
|
1290
1387
|
while (cur)
|
1291
1388
|
{
|
1292
1389
|
// get the head
|
1293
1390
|
head = cur->head_;
|
1294
1391
|
// abort (and return) if it is not a parent selector
|
1295
|
-
if (!head || head->length() != 1 || !
|
1392
|
+
if (!head || head->length() != 1 || !SASS_MEMORY_CAST(Parent_Selector, (*head)[0])) {
|
1296
1393
|
break;
|
1297
1394
|
}
|
1298
1395
|
// advance to next
|
1299
1396
|
cur = cur->tail_;
|
1300
1397
|
}
|
1301
1398
|
// result
|
1302
|
-
return cur;
|
1303
|
-
}
|
1304
|
-
|
1305
|
-
// return the last tail that is defined
|
1306
|
-
const Sequence_Selector* Sequence_Selector::first() const
|
1307
|
-
{
|
1308
|
-
// declare variables used in loop
|
1309
|
-
const Sequence_Selector* cur = this->tail_;
|
1310
|
-
const SimpleSequence_Selector* head = head_;
|
1311
|
-
// processing loop
|
1312
|
-
while (cur)
|
1313
|
-
{
|
1314
|
-
// get the head
|
1315
|
-
head = cur->head_;
|
1316
|
-
// check for single parent ref
|
1317
|
-
if (head && head->length() == 1)
|
1318
|
-
{
|
1319
|
-
// abort (and return) if it is not a parent selector
|
1320
|
-
if (!dynamic_cast<Parent_Selector*>((*head)[0])) break;
|
1321
|
-
}
|
1322
|
-
// advance to next
|
1323
|
-
cur = cur->tail_;
|
1324
|
-
}
|
1325
|
-
// result
|
1326
|
-
return cur;
|
1399
|
+
return &cur;
|
1327
1400
|
}
|
1328
1401
|
|
1329
1402
|
// return the last tail that is defined
|
1330
|
-
|
1403
|
+
Complex_Selector_Obj Complex_Selector::last()
|
1331
1404
|
{
|
1332
1405
|
// ToDo: implement with a while loop
|
1333
1406
|
return tail_? tail_->last() : this;
|
1334
1407
|
}
|
1335
1408
|
|
1336
|
-
|
1337
|
-
const Sequence_Selector* Sequence_Selector::last() const
|
1338
|
-
{
|
1339
|
-
// ToDo: implement with a while loop
|
1340
|
-
return tail_? tail_->last() : this;
|
1341
|
-
}
|
1342
|
-
|
1343
|
-
|
1344
|
-
Sequence_Selector::Combinator Sequence_Selector::clear_innermost()
|
1409
|
+
Complex_Selector::Combinator Complex_Selector::clear_innermost()
|
1345
1410
|
{
|
1346
1411
|
Combinator c;
|
1347
1412
|
if (!tail() || tail()->tail() == 0)
|
@@ -1351,7 +1416,7 @@ namespace Sass {
|
|
1351
1416
|
return c;
|
1352
1417
|
}
|
1353
1418
|
|
1354
|
-
void
|
1419
|
+
void Complex_Selector::set_innermost(Complex_Selector_Obj val, Combinator c)
|
1355
1420
|
{
|
1356
1421
|
if (!tail())
|
1357
1422
|
{ tail(val); combinator(c); }
|
@@ -1359,76 +1424,42 @@ namespace Sass {
|
|
1359
1424
|
{ tail()->set_innermost(val, c); }
|
1360
1425
|
}
|
1361
1426
|
|
1362
|
-
|
1427
|
+
void Complex_Selector::cloneChildren()
|
1363
1428
|
{
|
1364
|
-
|
1365
|
-
|
1366
|
-
cpy->media_block(this->media_block());
|
1367
|
-
if (tail()) cpy->tail(tail()->clone(ctx));
|
1368
|
-
return cpy;
|
1429
|
+
if (head()) head(SASS_MEMORY_CLONE(head()));
|
1430
|
+
if (tail()) tail(SASS_MEMORY_CLONE(tail()));
|
1369
1431
|
}
|
1370
1432
|
|
1371
|
-
|
1433
|
+
void Compound_Selector::cloneChildren()
|
1372
1434
|
{
|
1373
|
-
|
1374
|
-
|
1375
|
-
cpy->media_block(this->media_block());
|
1376
|
-
if (head()) {
|
1377
|
-
cpy->head(head()->clone(ctx));
|
1378
|
-
}
|
1379
|
-
|
1380
|
-
if (tail()) {
|
1381
|
-
cpy->tail(tail()->cloneFully(ctx));
|
1435
|
+
for (size_t i = 0, l = length(); i < l; i++) {
|
1436
|
+
at(i) = SASS_MEMORY_CLONE(at(i));
|
1382
1437
|
}
|
1383
|
-
|
1384
|
-
return cpy;
|
1385
1438
|
}
|
1386
1439
|
|
1387
|
-
|
1440
|
+
void Selector_List::cloneChildren()
|
1388
1441
|
{
|
1389
|
-
|
1390
|
-
|
1391
|
-
cpy->media_block(this->media_block());
|
1392
|
-
cpy->extended(this->extended());
|
1393
|
-
return cpy;
|
1394
|
-
}
|
1395
|
-
|
1396
|
-
CommaSequence_Selector* CommaSequence_Selector::clone(Context& ctx) const
|
1397
|
-
{
|
1398
|
-
CommaSequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, *this);
|
1399
|
-
cpy->is_optional(this->is_optional());
|
1400
|
-
cpy->media_block(this->media_block());
|
1401
|
-
return cpy;
|
1402
|
-
}
|
1403
|
-
|
1404
|
-
CommaSequence_Selector* CommaSequence_Selector::cloneFully(Context& ctx) const
|
1405
|
-
{
|
1406
|
-
CommaSequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, pstate());
|
1407
|
-
cpy->is_optional(this->is_optional());
|
1408
|
-
cpy->media_block(this->media_block());
|
1409
|
-
for (size_t i = 0, L = length(); i < L; ++i) {
|
1410
|
-
*cpy << (*this)[i]->cloneFully(ctx);
|
1442
|
+
for (size_t i = 0, l = length(); i < l; i++) {
|
1443
|
+
at(i) = SASS_MEMORY_CLONE(at(i));
|
1411
1444
|
}
|
1412
|
-
return cpy;
|
1413
1445
|
}
|
1414
1446
|
|
1415
|
-
|
1416
|
-
Placeholder_Selector* Selector::find_placeholder()
|
1447
|
+
void Wrapped_Selector::cloneChildren()
|
1417
1448
|
{
|
1418
|
-
|
1419
|
-
}
|
1449
|
+
selector(SASS_MEMORY_CLONE(selector()));
|
1450
|
+
}
|
1420
1451
|
|
1421
1452
|
// remove parent selector references
|
1422
1453
|
// basically unwraps parsed selectors
|
1423
|
-
void
|
1454
|
+
void Selector_List::remove_parent_selectors()
|
1424
1455
|
{
|
1425
1456
|
// Check every rhs selector against left hand list
|
1426
1457
|
for(size_t i = 0, L = length(); i < L; ++i) {
|
1427
1458
|
if (!(*this)[i]->head()) continue;
|
1428
1459
|
if ((*this)[i]->head()->is_empty_reference()) {
|
1429
1460
|
// simply move to the next tail if we have "no" combinator
|
1430
|
-
if ((*this)[i]->combinator() ==
|
1431
|
-
if ((*this)[i]->tail()
|
1461
|
+
if ((*this)[i]->combinator() == Complex_Selector::ANCESTOR_OF) {
|
1462
|
+
if ((*this)[i]->tail()) {
|
1432
1463
|
if ((*this)[i]->has_line_feed()) {
|
1433
1464
|
(*this)[i]->tail()->has_line_feed(true);
|
1434
1465
|
}
|
@@ -1443,17 +1474,17 @@ namespace Sass {
|
|
1443
1474
|
}
|
1444
1475
|
}
|
1445
1476
|
|
1446
|
-
bool
|
1477
|
+
bool Selector_List::has_parent_ref()
|
1447
1478
|
{
|
1448
|
-
for (
|
1479
|
+
for (Complex_Selector_Obj s : elements()) {
|
1449
1480
|
if (s && s->has_parent_ref()) return true;
|
1450
1481
|
}
|
1451
1482
|
return false;
|
1452
1483
|
}
|
1453
1484
|
|
1454
|
-
bool
|
1485
|
+
bool Selector_List::has_real_parent_ref()
|
1455
1486
|
{
|
1456
|
-
for (
|
1487
|
+
for (Complex_Selector_Obj s : elements()) {
|
1457
1488
|
if (s && s->has_real_parent_ref()) return true;
|
1458
1489
|
}
|
1459
1490
|
return false;
|
@@ -1461,51 +1492,51 @@ namespace Sass {
|
|
1461
1492
|
|
1462
1493
|
bool Selector_Schema::has_parent_ref()
|
1463
1494
|
{
|
1464
|
-
if (
|
1465
|
-
return schema->length() > 0 &&
|
1495
|
+
if (String_Schema_Obj schema = SASS_MEMORY_CAST(String_Schema, contents())) {
|
1496
|
+
return schema->length() > 0 && SASS_MEMORY_CAST(Parent_Selector, schema->at(0)) != NULL;
|
1466
1497
|
}
|
1467
1498
|
return false;
|
1468
1499
|
}
|
1469
1500
|
|
1470
1501
|
bool Selector_Schema::has_real_parent_ref()
|
1471
1502
|
{
|
1472
|
-
if (
|
1473
|
-
|
1474
|
-
return schema->length() > 0 && p
|
1503
|
+
if (String_Schema_Obj schema = SASS_MEMORY_CAST(String_Schema, contents())) {
|
1504
|
+
Parent_Selector_Obj p = SASS_MEMORY_CAST(Parent_Selector, schema->at(0));
|
1505
|
+
return schema->length() > 0 && p && p->is_real_parent_ref();
|
1475
1506
|
}
|
1476
1507
|
return false;
|
1477
1508
|
}
|
1478
1509
|
|
1479
|
-
void
|
1510
|
+
void Selector_List::adjust_after_pushing(Complex_Selector_Obj c)
|
1480
1511
|
{
|
1481
1512
|
// if (c->has_reference()) has_reference(true);
|
1482
1513
|
}
|
1483
1514
|
|
1484
1515
|
// it's a superselector if every selector of the right side
|
1485
1516
|
// list is a superselector of the given left side selector
|
1486
|
-
bool
|
1517
|
+
bool Complex_Selector::is_superselector_of(Selector_List_Obj sub, std::string wrapping)
|
1487
1518
|
{
|
1488
1519
|
// Check every rhs selector against left hand list
|
1489
1520
|
for(size_t i = 0, L = sub->length(); i < L; ++i) {
|
1490
|
-
if (!is_superselector_of((*sub)[i], wrapping)) return false;
|
1521
|
+
if (!is_superselector_of(&(*sub)[i], wrapping)) return false;
|
1491
1522
|
}
|
1492
1523
|
return true;
|
1493
1524
|
}
|
1494
1525
|
|
1495
1526
|
// it's a superselector if every selector of the right side
|
1496
1527
|
// list is a superselector of the given left side selector
|
1497
|
-
bool
|
1528
|
+
bool Selector_List::is_superselector_of(Selector_List_Obj sub, std::string wrapping)
|
1498
1529
|
{
|
1499
1530
|
// Check every rhs selector against left hand list
|
1500
1531
|
for(size_t i = 0, L = sub->length(); i < L; ++i) {
|
1501
|
-
if (!is_superselector_of((*sub)[i], wrapping)) return false;
|
1532
|
+
if (!is_superselector_of(&(*sub)[i], wrapping)) return false;
|
1502
1533
|
}
|
1503
1534
|
return true;
|
1504
1535
|
}
|
1505
1536
|
|
1506
1537
|
// it's a superselector if every selector on the right side
|
1507
1538
|
// is a superselector of any one of the left side selectors
|
1508
|
-
bool
|
1539
|
+
bool Selector_List::is_superselector_of(Compound_Selector_Obj sub, std::string wrapping)
|
1509
1540
|
{
|
1510
1541
|
// Check every lhs selector against right hand
|
1511
1542
|
for(size_t i = 0, L = length(); i < L; ++i) {
|
@@ -1516,7 +1547,7 @@ namespace Sass {
|
|
1516
1547
|
|
1517
1548
|
// it's a superselector if every selector on the right side
|
1518
1549
|
// is a superselector of any one of the left side selectors
|
1519
|
-
bool
|
1550
|
+
bool Selector_List::is_superselector_of(Complex_Selector_Obj sub, std::string wrapping)
|
1520
1551
|
{
|
1521
1552
|
// Check every lhs selector against right hand
|
1522
1553
|
for(size_t i = 0, L = length(); i < L; ++i) {
|
@@ -1525,45 +1556,45 @@ namespace Sass {
|
|
1525
1556
|
return false;
|
1526
1557
|
}
|
1527
1558
|
|
1528
|
-
|
1529
|
-
std::vector<
|
1559
|
+
Selector_List_Ptr Selector_List::unify_with(Selector_List_Ptr rhs, Context& ctx) {
|
1560
|
+
std::vector<Complex_Selector_Obj> unified_complex_selectors;
|
1530
1561
|
// Unify all of children with RHS's children, storing the results in `unified_complex_selectors`
|
1531
1562
|
for (size_t lhs_i = 0, lhs_L = length(); lhs_i < lhs_L; ++lhs_i) {
|
1532
|
-
|
1563
|
+
Complex_Selector_Obj seq1 = (*this)[lhs_i];
|
1533
1564
|
for(size_t rhs_i = 0, rhs_L = rhs->length(); rhs_i < rhs_L; ++rhs_i) {
|
1534
|
-
|
1565
|
+
Complex_Selector_Ptr seq2 = &rhs->at(rhs_i);
|
1535
1566
|
|
1536
|
-
|
1567
|
+
Selector_List_Obj result = seq1->unify_with(seq2, ctx);
|
1537
1568
|
if( result ) {
|
1538
1569
|
for(size_t i = 0, L = result->length(); i < L; ++i) {
|
1539
|
-
unified_complex_selectors.push_back( (*result)[i] );
|
1570
|
+
unified_complex_selectors.push_back( &(*result)[i] );
|
1540
1571
|
}
|
1541
1572
|
}
|
1542
1573
|
}
|
1543
1574
|
}
|
1544
1575
|
|
1545
|
-
// Creates the final
|
1546
|
-
|
1576
|
+
// Creates the final Selector_List by combining all the complex selectors
|
1577
|
+
Selector_List_Ptr final_result = SASS_MEMORY_NEW(Selector_List, pstate());
|
1547
1578
|
for (auto itr = unified_complex_selectors.begin(); itr != unified_complex_selectors.end(); ++itr) {
|
1548
|
-
|
1579
|
+
final_result->append(*itr);
|
1549
1580
|
}
|
1550
1581
|
return final_result;
|
1551
1582
|
}
|
1552
1583
|
|
1553
|
-
void
|
1584
|
+
void Selector_List::populate_extends(Selector_List_Obj extendee, Context& ctx, Subset_Map& extends)
|
1554
1585
|
{
|
1555
1586
|
|
1556
|
-
|
1587
|
+
Selector_List_Ptr extender = this;
|
1557
1588
|
for (auto complex_sel : extendee->elements()) {
|
1558
|
-
|
1589
|
+
Complex_Selector_Obj c = complex_sel;
|
1559
1590
|
|
1560
1591
|
|
1561
|
-
// Ignore any parent selectors, until we find the first non
|
1562
|
-
|
1563
|
-
|
1592
|
+
// Ignore any parent selectors, until we find the first non Selectorerence head
|
1593
|
+
Compound_Selector_Obj compound_sel = c->head();
|
1594
|
+
Complex_Selector_Obj pIter = complex_sel;
|
1564
1595
|
while (pIter) {
|
1565
|
-
|
1566
|
-
if (pHead &&
|
1596
|
+
Compound_Selector_Obj pHead = pIter->head();
|
1597
|
+
if (pHead && SASS_MEMORY_CAST(Parent_Selector, pHead->elements()[0]) == NULL) {
|
1567
1598
|
compound_sel = pHead;
|
1568
1599
|
break;
|
1569
1600
|
}
|
@@ -1578,30 +1609,28 @@ namespace Sass {
|
|
1578
1609
|
compound_sel->is_optional(extendee->is_optional());
|
1579
1610
|
|
1580
1611
|
for (size_t i = 0, L = extender->length(); i < L; ++i) {
|
1581
|
-
extends.put(compound_sel
|
1612
|
+
extends.put(compound_sel, std::make_pair(&(*extender)[i], &compound_sel));
|
1582
1613
|
}
|
1583
1614
|
}
|
1584
1615
|
};
|
1585
1616
|
|
1586
|
-
std::vector<std::string>
|
1617
|
+
std::vector<std::string> Compound_Selector::to_str_vec()
|
1587
1618
|
{
|
1588
|
-
std::vector<std::string> result;
|
1589
|
-
result.reserve(length());
|
1619
|
+
std::vector<std::string> result(length());
|
1590
1620
|
for (size_t i = 0, L = length(); i < L; ++i)
|
1591
1621
|
{ result.push_back((*this)[i]->to_string()); }
|
1592
1622
|
return result;
|
1593
1623
|
}
|
1594
1624
|
|
1595
|
-
|
1625
|
+
void Compound_Selector::append(Simple_Selector_Ptr element)
|
1596
1626
|
{
|
1597
|
-
Vectorized<
|
1627
|
+
Vectorized<Simple_Selector_Obj>::append(element);
|
1598
1628
|
pstate_.offset += element->pstate().offset;
|
1599
|
-
return *this;
|
1600
1629
|
}
|
1601
1630
|
|
1602
|
-
|
1631
|
+
Compound_Selector_Ptr Compound_Selector::minus(Compound_Selector_Ptr rhs, Context& ctx)
|
1603
1632
|
{
|
1604
|
-
|
1633
|
+
Compound_Selector_Ptr result = SASS_MEMORY_NEW(Compound_Selector, pstate());
|
1605
1634
|
// result->has_parent_reference(has_parent_reference());
|
1606
1635
|
|
1607
1636
|
// not very efficient because it needs to preserve order
|
@@ -1617,50 +1646,44 @@ namespace Sass {
|
|
1617
1646
|
break;
|
1618
1647
|
}
|
1619
1648
|
}
|
1620
|
-
if (!found)
|
1649
|
+
if (!found) result->append(&(*this)[i]);
|
1621
1650
|
}
|
1622
1651
|
|
1623
1652
|
return result;
|
1624
1653
|
}
|
1625
1654
|
|
1626
|
-
void
|
1655
|
+
void Compound_Selector::mergeSources(SourcesSet& sources, Context& ctx)
|
1627
1656
|
{
|
1628
1657
|
for (SourcesSet::iterator iterator = sources.begin(), endIterator = sources.end(); iterator != endIterator; ++iterator) {
|
1629
|
-
this->sources_.insert((*iterator)
|
1658
|
+
this->sources_.insert(SASS_MEMORY_CLONE(*iterator));
|
1630
1659
|
}
|
1631
1660
|
}
|
1632
1661
|
|
1633
|
-
|
1662
|
+
Argument_Obj Arguments::get_rest_argument()
|
1634
1663
|
{
|
1635
|
-
Argument* arg = 0;
|
1636
1664
|
if (this->has_rest_argument()) {
|
1637
|
-
for (
|
1638
|
-
if (
|
1639
|
-
arg
|
1640
|
-
break;
|
1665
|
+
for (Argument_Obj arg : this->elements()) {
|
1666
|
+
if (arg->is_rest_argument()) {
|
1667
|
+
return arg;
|
1641
1668
|
}
|
1642
1669
|
}
|
1643
1670
|
}
|
1644
|
-
|
1645
|
-
return arg;
|
1671
|
+
return NULL;
|
1646
1672
|
}
|
1647
1673
|
|
1648
|
-
|
1674
|
+
Argument_Obj Arguments::get_keyword_argument()
|
1649
1675
|
{
|
1650
|
-
Argument* arg = 0;
|
1651
1676
|
if (this->has_keyword_argument()) {
|
1652
|
-
for (
|
1653
|
-
if (
|
1654
|
-
arg
|
1655
|
-
break;
|
1677
|
+
for (Argument_Obj arg : this->elements()) {
|
1678
|
+
if (arg->is_keyword_argument()) {
|
1679
|
+
return arg;
|
1656
1680
|
}
|
1657
1681
|
}
|
1658
1682
|
}
|
1659
|
-
|
1660
|
-
return arg;
|
1683
|
+
return NULL;
|
1661
1684
|
}
|
1662
1685
|
|
1663
|
-
void Arguments::adjust_after_pushing(
|
1686
|
+
void Arguments::adjust_after_pushing(Argument_Obj a)
|
1664
1687
|
{
|
1665
1688
|
if (!a->name().empty()) {
|
1666
1689
|
if (/* has_rest_argument_ || */ has_keyword_argument_) {
|
@@ -1694,7 +1717,7 @@ namespace Sass {
|
|
1694
1717
|
}
|
1695
1718
|
|
1696
1719
|
bool Ruleset::is_invisible() const {
|
1697
|
-
if (
|
1720
|
+
if (Selector_List_Ptr sl = SASS_MEMORY_CAST(Selector_List, selector())) {
|
1698
1721
|
for (size_t i = 0, L = sl->length(); i < L; ++i)
|
1699
1722
|
if (!(*sl)[i]->has_placeholder()) return false;
|
1700
1723
|
}
|
@@ -1703,7 +1726,8 @@ namespace Sass {
|
|
1703
1726
|
|
1704
1727
|
bool Media_Block::is_invisible() const {
|
1705
1728
|
for (size_t i = 0, L = block()->length(); i < L; ++i) {
|
1706
|
-
|
1729
|
+
Statement_Obj stm = block()->at(i);
|
1730
|
+
if (!stm->is_invisible()) return false;
|
1707
1731
|
}
|
1708
1732
|
return true;
|
1709
1733
|
}
|
@@ -2070,7 +2094,7 @@ namespace Sass {
|
|
2070
2094
|
|
2071
2095
|
bool Custom_Warning::operator== (const Expression& rhs) const
|
2072
2096
|
{
|
2073
|
-
if (
|
2097
|
+
if (Custom_Warning_Ptr_Const r = dynamic_cast<Custom_Warning_Ptr_Const>(&rhs)) {
|
2074
2098
|
return message() == r->message();
|
2075
2099
|
}
|
2076
2100
|
return false;
|
@@ -2078,7 +2102,7 @@ namespace Sass {
|
|
2078
2102
|
|
2079
2103
|
bool Custom_Error::operator== (const Expression& rhs) const
|
2080
2104
|
{
|
2081
|
-
if (
|
2105
|
+
if (Custom_Error_Ptr_Const r = dynamic_cast<Custom_Error_Ptr_Const>(&rhs)) {
|
2082
2106
|
return message() == r->message();
|
2083
2107
|
}
|
2084
2108
|
return false;
|
@@ -2086,7 +2110,7 @@ namespace Sass {
|
|
2086
2110
|
|
2087
2111
|
bool Number::eq (const Expression& rhs) const
|
2088
2112
|
{
|
2089
|
-
if (
|
2113
|
+
if (Number_Ptr_Const r = dynamic_cast<Number_Ptr_Const>(&rhs)) {
|
2090
2114
|
size_t lhs_units = numerator_units_.size() + denominator_units_.size();
|
2091
2115
|
size_t rhs_units = r->numerator_units_.size() + r->denominator_units_.size();
|
2092
2116
|
if (!lhs_units && !rhs_units) {
|
@@ -2101,7 +2125,7 @@ namespace Sass {
|
|
2101
2125
|
|
2102
2126
|
bool Number::operator== (const Expression& rhs) const
|
2103
2127
|
{
|
2104
|
-
if (
|
2128
|
+
if (Number_Ptr_Const r = dynamic_cast<Number_Ptr_Const>(&rhs)) {
|
2105
2129
|
size_t lhs_units = numerator_units_.size() + denominator_units_.size();
|
2106
2130
|
size_t rhs_units = r->numerator_units_.size() + r->denominator_units_.size();
|
2107
2131
|
// unitless and only having one unit seems equivalent (will change in future)
|
@@ -2124,7 +2148,7 @@ namespace Sass {
|
|
2124
2148
|
return value() < rhs.value();
|
2125
2149
|
}
|
2126
2150
|
|
2127
|
-
Number tmp_r(rhs);
|
2151
|
+
Number tmp_r(&rhs); // copy
|
2128
2152
|
tmp_r.normalize(find_convertible_unit());
|
2129
2153
|
std::string l_unit(unit());
|
2130
2154
|
std::string r_unit(tmp_r.unit());
|
@@ -2136,9 +2160,9 @@ namespace Sass {
|
|
2136
2160
|
|
2137
2161
|
bool String_Quoted::operator== (const Expression& rhs) const
|
2138
2162
|
{
|
2139
|
-
if (
|
2163
|
+
if (String_Quoted_Ptr_Const qstr = dynamic_cast<String_Quoted_Ptr_Const>(&rhs)) {
|
2140
2164
|
return (value() == qstr->value());
|
2141
|
-
} else if (
|
2165
|
+
} else if (String_Constant_Ptr_Const cstr = dynamic_cast<String_Constant_Ptr_Const>(&rhs)) {
|
2142
2166
|
return (value() == cstr->value());
|
2143
2167
|
}
|
2144
2168
|
return false;
|
@@ -2150,9 +2174,9 @@ namespace Sass {
|
|
2150
2174
|
|
2151
2175
|
bool String_Constant::operator== (const Expression& rhs) const
|
2152
2176
|
{
|
2153
|
-
if (
|
2177
|
+
if (String_Quoted_Ptr_Const qstr = dynamic_cast<String_Quoted_Ptr_Const>(&rhs)) {
|
2154
2178
|
return (value() == qstr->value());
|
2155
|
-
} else if (
|
2179
|
+
} else if (String_Constant_Ptr_Const cstr = dynamic_cast<String_Constant_Ptr_Const>(&rhs)) {
|
2156
2180
|
return (value() == cstr->value());
|
2157
2181
|
}
|
2158
2182
|
return false;
|
@@ -2169,11 +2193,11 @@ namespace Sass {
|
|
2169
2193
|
|
2170
2194
|
bool String_Schema::operator== (const Expression& rhs) const
|
2171
2195
|
{
|
2172
|
-
if (
|
2196
|
+
if (String_Schema_Ptr_Const r = dynamic_cast<String_Schema_Ptr_Const>(&rhs)) {
|
2173
2197
|
if (length() != r->length()) return false;
|
2174
2198
|
for (size_t i = 0, L = length(); i < L; ++i) {
|
2175
|
-
|
2176
|
-
|
2199
|
+
Expression_Obj rv = (*r)[i];
|
2200
|
+
Expression_Obj lv = (*this)[i];
|
2177
2201
|
if (!lv || !rv) return false;
|
2178
2202
|
if (!(*lv == *rv)) return false;
|
2179
2203
|
}
|
@@ -2184,7 +2208,7 @@ namespace Sass {
|
|
2184
2208
|
|
2185
2209
|
bool Boolean::operator== (const Expression& rhs) const
|
2186
2210
|
{
|
2187
|
-
if (
|
2211
|
+
if (Boolean_Ptr_Const r = dynamic_cast<Boolean_Ptr_Const>(&rhs)) {
|
2188
2212
|
return (value() == r->value());
|
2189
2213
|
}
|
2190
2214
|
return false;
|
@@ -2192,7 +2216,7 @@ namespace Sass {
|
|
2192
2216
|
|
2193
2217
|
bool Color::operator== (const Expression& rhs) const
|
2194
2218
|
{
|
2195
|
-
if (
|
2219
|
+
if (Color_Ptr_Const r = dynamic_cast<Color_Ptr_Const>(&rhs)) {
|
2196
2220
|
return r_ == r->r() &&
|
2197
2221
|
g_ == r->g() &&
|
2198
2222
|
b_ == r->b() &&
|
@@ -2203,12 +2227,12 @@ namespace Sass {
|
|
2203
2227
|
|
2204
2228
|
bool List::operator== (const Expression& rhs) const
|
2205
2229
|
{
|
2206
|
-
if (
|
2230
|
+
if (List_Ptr_Const r = dynamic_cast<List_Ptr_Const>(&rhs)) {
|
2207
2231
|
if (length() != r->length()) return false;
|
2208
2232
|
if (separator() != r->separator()) return false;
|
2209
2233
|
for (size_t i = 0, L = length(); i < L; ++i) {
|
2210
|
-
|
2211
|
-
|
2234
|
+
Expression_Obj rv = r->at(i);
|
2235
|
+
Expression_Obj lv = this->at(i);
|
2212
2236
|
if (!lv || !rv) return false;
|
2213
2237
|
if (!(*lv == *rv)) return false;
|
2214
2238
|
}
|
@@ -2219,11 +2243,11 @@ namespace Sass {
|
|
2219
2243
|
|
2220
2244
|
bool Map::operator== (const Expression& rhs) const
|
2221
2245
|
{
|
2222
|
-
if (
|
2246
|
+
if (Map_Ptr_Const r = dynamic_cast<Map_Ptr_Const>(&rhs)) {
|
2223
2247
|
if (length() != r->length()) return false;
|
2224
2248
|
for (auto key : keys()) {
|
2225
|
-
|
2226
|
-
|
2249
|
+
Expression_Obj lv = at(key);
|
2250
|
+
Expression_Obj rv = r->at(key);
|
2227
2251
|
if (!rv || !lv) return false;
|
2228
2252
|
if (!(*lv == *rv)) return false;
|
2229
2253
|
}
|
@@ -2242,18 +2266,19 @@ namespace Sass {
|
|
2242
2266
|
// arglist expects a list of arguments
|
2243
2267
|
// so we need to break before keywords
|
2244
2268
|
for (size_t i = 0, L = length(); i < L; ++i) {
|
2245
|
-
|
2269
|
+
Expression_Obj obj = this->at(i);
|
2270
|
+
if (Argument* arg = dynamic_cast<Argument*>(&obj)) {
|
2246
2271
|
if (!arg->name().empty()) return i;
|
2247
2272
|
}
|
2248
2273
|
}
|
2249
2274
|
return length();
|
2250
2275
|
}
|
2251
2276
|
|
2252
|
-
|
2277
|
+
Expression_Obj Hashed::at(Expression_Obj k) const
|
2253
2278
|
{
|
2254
2279
|
if (elements_.count(k))
|
2255
2280
|
{ return elements_.at(k); }
|
2256
|
-
else { return
|
2281
|
+
else { return NULL; }
|
2257
2282
|
}
|
2258
2283
|
|
2259
2284
|
bool Binary_Expression::is_left_interpolant(void) const
|
@@ -2272,7 +2297,7 @@ namespace Sass {
|
|
2272
2297
|
Inspect i(emitter);
|
2273
2298
|
i.in_declaration = true;
|
2274
2299
|
// ToDo: inspect should be const
|
2275
|
-
const_cast<
|
2300
|
+
const_cast<AST_Node_Ptr>(this)->perform(&i);
|
2276
2301
|
return i.get_buffer();
|
2277
2302
|
}
|
2278
2303
|
|
@@ -2294,32 +2319,133 @@ namespace Sass {
|
|
2294
2319
|
//////////////////////////////////////////////////////////////////////////////////////////
|
2295
2320
|
// Additional method on Lists to retrieve values directly or from an encompassed Argument.
|
2296
2321
|
//////////////////////////////////////////////////////////////////////////////////////////
|
2297
|
-
|
2322
|
+
Expression_Obj List::value_at_index(size_t i) {
|
2323
|
+
Expression_Obj obj = this->at(i);
|
2298
2324
|
if (is_arglist_) {
|
2299
|
-
if (Argument* arg = dynamic_cast<Argument*>(
|
2325
|
+
if (Argument* arg = dynamic_cast<Argument*>(&obj)) {
|
2300
2326
|
return arg->value();
|
2301
2327
|
} else {
|
2302
|
-
return
|
2328
|
+
return &obj;
|
2303
2329
|
}
|
2304
2330
|
} else {
|
2305
|
-
return
|
2331
|
+
return &obj;
|
2306
2332
|
}
|
2307
2333
|
}
|
2308
2334
|
|
2309
2335
|
//////////////////////////////////////////////////////////////////////////////////////////
|
2310
2336
|
// Convert map to (key, value) list.
|
2311
2337
|
//////////////////////////////////////////////////////////////////////////////////////////
|
2312
|
-
|
2313
|
-
|
2338
|
+
List_Obj Map::to_list(Context& ctx, ParserState& pstate) {
|
2339
|
+
List_Obj ret = SASS_MEMORY_NEW(List, pstate, length(), SASS_COMMA);
|
2314
2340
|
|
2315
2341
|
for (auto key : keys()) {
|
2316
|
-
|
2317
|
-
|
2318
|
-
|
2319
|
-
|
2342
|
+
List_Obj l = SASS_MEMORY_NEW(List, pstate, 2);
|
2343
|
+
l->append(&key);
|
2344
|
+
l->append(at(key));
|
2345
|
+
ret->append(&l);
|
2320
2346
|
}
|
2321
2347
|
|
2322
2348
|
return ret;
|
2323
2349
|
}
|
2324
2350
|
|
2351
|
+
//////////////////////////////////////////////////////////////////////////////////////////
|
2352
|
+
// Copy implementations
|
2353
|
+
//////////////////////////////////////////////////////////////////////////////////////////
|
2354
|
+
|
2355
|
+
#ifdef DEBUG_SHARED_PTR
|
2356
|
+
|
2357
|
+
#define IMPLEMENT_AST_OPERATORS(klass) \
|
2358
|
+
klass##_Ptr klass::copy(std::string file, size_t line) const { \
|
2359
|
+
klass##_Ptr cpy = new klass(this); \
|
2360
|
+
cpy->trace(file, line); \
|
2361
|
+
return cpy; \
|
2362
|
+
} \
|
2363
|
+
klass##_Ptr klass::clone(std::string file, size_t line) const { \
|
2364
|
+
klass##_Ptr cpy = copy(file, line); \
|
2365
|
+
cpy->cloneChildren(); \
|
2366
|
+
return cpy; \
|
2367
|
+
} \
|
2368
|
+
|
2369
|
+
#else
|
2370
|
+
|
2371
|
+
#define IMPLEMENT_AST_OPERATORS(klass) \
|
2372
|
+
klass##_Ptr klass::copy() const { \
|
2373
|
+
return new klass(this); \
|
2374
|
+
} \
|
2375
|
+
klass##_Ptr klass::clone() const { \
|
2376
|
+
klass##_Ptr cpy = copy(); \
|
2377
|
+
cpy->cloneChildren(); \
|
2378
|
+
return cpy; \
|
2379
|
+
} \
|
2380
|
+
|
2381
|
+
#endif
|
2382
|
+
|
2383
|
+
IMPLEMENT_AST_OPERATORS(Supports_Operator);
|
2384
|
+
IMPLEMENT_AST_OPERATORS(Supports_Negation);
|
2385
|
+
IMPLEMENT_AST_OPERATORS(Compound_Selector);
|
2386
|
+
IMPLEMENT_AST_OPERATORS(Complex_Selector);
|
2387
|
+
IMPLEMENT_AST_OPERATORS(Element_Selector);
|
2388
|
+
IMPLEMENT_AST_OPERATORS(Class_Selector);
|
2389
|
+
IMPLEMENT_AST_OPERATORS(Id_Selector);
|
2390
|
+
IMPLEMENT_AST_OPERATORS(Pseudo_Selector);
|
2391
|
+
IMPLEMENT_AST_OPERATORS(Wrapped_Selector);
|
2392
|
+
IMPLEMENT_AST_OPERATORS(Selector_List);
|
2393
|
+
IMPLEMENT_AST_OPERATORS(Ruleset);
|
2394
|
+
IMPLEMENT_AST_OPERATORS(Media_Block);
|
2395
|
+
IMPLEMENT_AST_OPERATORS(Custom_Warning);
|
2396
|
+
IMPLEMENT_AST_OPERATORS(Custom_Error);
|
2397
|
+
IMPLEMENT_AST_OPERATORS(List);
|
2398
|
+
IMPLEMENT_AST_OPERATORS(Map);
|
2399
|
+
IMPLEMENT_AST_OPERATORS(Number);
|
2400
|
+
IMPLEMENT_AST_OPERATORS(Binary_Expression);
|
2401
|
+
IMPLEMENT_AST_OPERATORS(String_Schema);
|
2402
|
+
IMPLEMENT_AST_OPERATORS(String_Constant);
|
2403
|
+
IMPLEMENT_AST_OPERATORS(String_Quoted);
|
2404
|
+
IMPLEMENT_AST_OPERATORS(Boolean);
|
2405
|
+
IMPLEMENT_AST_OPERATORS(Color);
|
2406
|
+
IMPLEMENT_AST_OPERATORS(Null);
|
2407
|
+
IMPLEMENT_AST_OPERATORS(Parent_Selector);
|
2408
|
+
IMPLEMENT_AST_OPERATORS(Import);
|
2409
|
+
IMPLEMENT_AST_OPERATORS(Import_Stub);
|
2410
|
+
IMPLEMENT_AST_OPERATORS(Function_Call);
|
2411
|
+
IMPLEMENT_AST_OPERATORS(Directive);
|
2412
|
+
IMPLEMENT_AST_OPERATORS(At_Root_Block);
|
2413
|
+
IMPLEMENT_AST_OPERATORS(Supports_Block);
|
2414
|
+
IMPLEMENT_AST_OPERATORS(While);
|
2415
|
+
IMPLEMENT_AST_OPERATORS(Each);
|
2416
|
+
IMPLEMENT_AST_OPERATORS(For);
|
2417
|
+
IMPLEMENT_AST_OPERATORS(If);
|
2418
|
+
IMPLEMENT_AST_OPERATORS(Mixin_Call);
|
2419
|
+
IMPLEMENT_AST_OPERATORS(Extension);
|
2420
|
+
IMPLEMENT_AST_OPERATORS(Media_Query);
|
2421
|
+
IMPLEMENT_AST_OPERATORS(Media_Query_Expression);
|
2422
|
+
IMPLEMENT_AST_OPERATORS(Debug);
|
2423
|
+
IMPLEMENT_AST_OPERATORS(Error);
|
2424
|
+
IMPLEMENT_AST_OPERATORS(Warning);
|
2425
|
+
IMPLEMENT_AST_OPERATORS(Assignment);
|
2426
|
+
IMPLEMENT_AST_OPERATORS(Return);
|
2427
|
+
IMPLEMENT_AST_OPERATORS(At_Root_Query);
|
2428
|
+
IMPLEMENT_AST_OPERATORS(Variable);
|
2429
|
+
IMPLEMENT_AST_OPERATORS(Comment);
|
2430
|
+
IMPLEMENT_AST_OPERATORS(Attribute_Selector);
|
2431
|
+
IMPLEMENT_AST_OPERATORS(Supports_Interpolation);
|
2432
|
+
IMPLEMENT_AST_OPERATORS(Supports_Declaration);
|
2433
|
+
IMPLEMENT_AST_OPERATORS(Supports_Condition);
|
2434
|
+
IMPLEMENT_AST_OPERATORS(Parameters);
|
2435
|
+
IMPLEMENT_AST_OPERATORS(Parameter);
|
2436
|
+
IMPLEMENT_AST_OPERATORS(Arguments);
|
2437
|
+
IMPLEMENT_AST_OPERATORS(Argument);
|
2438
|
+
IMPLEMENT_AST_OPERATORS(Unary_Expression);
|
2439
|
+
IMPLEMENT_AST_OPERATORS(Function_Call_Schema);
|
2440
|
+
IMPLEMENT_AST_OPERATORS(Block);
|
2441
|
+
IMPLEMENT_AST_OPERATORS(Content);
|
2442
|
+
IMPLEMENT_AST_OPERATORS(Textual);
|
2443
|
+
IMPLEMENT_AST_OPERATORS(Trace);
|
2444
|
+
IMPLEMENT_AST_OPERATORS(Keyframe_Rule);
|
2445
|
+
IMPLEMENT_AST_OPERATORS(Bubble);
|
2446
|
+
IMPLEMENT_AST_OPERATORS(Selector_Schema);
|
2447
|
+
IMPLEMENT_AST_OPERATORS(Placeholder_Selector);
|
2448
|
+
IMPLEMENT_AST_OPERATORS(Definition);
|
2449
|
+
IMPLEMENT_AST_OPERATORS(Declaration);
|
2450
|
+
|
2325
2451
|
}
|