sassc 2.2.1 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/CHANGELOG.md +18 -0
- data/Rakefile +1 -3
- data/ext/extconf.rb +13 -5
- data/ext/libsass/VERSION +1 -1
- data/ext/libsass/include/sass/base.h +2 -1
- data/ext/libsass/include/sass/context.h +4 -0
- data/ext/libsass/src/MurmurHash2.hpp +91 -0
- data/ext/libsass/src/ast.cpp +158 -168
- data/ext/libsass/src/ast.hpp +389 -230
- data/ext/libsass/src/ast_def_macros.hpp +18 -10
- data/ext/libsass/src/ast_fwd_decl.cpp +4 -3
- data/ext/libsass/src/ast_fwd_decl.hpp +98 -165
- data/ext/libsass/src/ast_helpers.hpp +292 -0
- data/ext/libsass/src/ast_sel_cmp.cpp +219 -732
- data/ext/libsass/src/ast_sel_super.cpp +539 -0
- data/ext/libsass/src/ast_sel_unify.cpp +207 -212
- data/ext/libsass/src/ast_sel_weave.cpp +616 -0
- data/ext/libsass/src/ast_selectors.cpp +594 -1026
- data/ext/libsass/src/ast_selectors.hpp +339 -385
- data/ext/libsass/src/ast_supports.cpp +36 -52
- data/ext/libsass/src/ast_supports.hpp +29 -29
- data/ext/libsass/src/ast_values.cpp +271 -84
- data/ext/libsass/src/ast_values.hpp +116 -107
- data/ext/libsass/src/backtrace.cpp +9 -9
- data/ext/libsass/src/backtrace.hpp +5 -5
- data/ext/libsass/src/base64vlq.cpp +2 -2
- data/ext/libsass/src/base64vlq.hpp +1 -1
- data/ext/libsass/src/bind.cpp +18 -18
- data/ext/libsass/src/bind.hpp +1 -1
- data/ext/libsass/src/c2ast.cpp +3 -3
- data/ext/libsass/src/c2ast.hpp +1 -1
- data/ext/libsass/src/cencode.c +4 -6
- data/ext/libsass/src/check_nesting.cpp +40 -41
- data/ext/libsass/src/check_nesting.hpp +6 -2
- data/ext/libsass/src/color_maps.cpp +14 -13
- data/ext/libsass/src/color_maps.hpp +1 -9
- data/ext/libsass/src/constants.cpp +5 -0
- data/ext/libsass/src/constants.hpp +6 -0
- data/ext/libsass/src/context.cpp +92 -119
- data/ext/libsass/src/context.hpp +41 -53
- data/ext/libsass/src/cssize.cpp +66 -149
- data/ext/libsass/src/cssize.hpp +17 -23
- data/ext/libsass/src/dart_helpers.hpp +199 -0
- data/ext/libsass/src/debugger.hpp +451 -295
- data/ext/libsass/src/emitter.cpp +15 -16
- data/ext/libsass/src/emitter.hpp +10 -12
- data/ext/libsass/src/environment.cpp +27 -27
- data/ext/libsass/src/environment.hpp +29 -24
- data/ext/libsass/src/error_handling.cpp +62 -41
- data/ext/libsass/src/error_handling.hpp +61 -51
- data/ext/libsass/src/eval.cpp +167 -281
- data/ext/libsass/src/eval.hpp +27 -29
- data/ext/libsass/src/eval_selectors.cpp +75 -0
- data/ext/libsass/src/expand.cpp +275 -222
- data/ext/libsass/src/expand.hpp +36 -16
- data/ext/libsass/src/extender.cpp +1188 -0
- data/ext/libsass/src/extender.hpp +399 -0
- data/ext/libsass/src/extension.cpp +43 -0
- data/ext/libsass/src/extension.hpp +89 -0
- data/ext/libsass/src/file.cpp +81 -72
- data/ext/libsass/src/file.hpp +28 -37
- data/ext/libsass/src/fn_colors.cpp +20 -18
- data/ext/libsass/src/fn_lists.cpp +30 -29
- data/ext/libsass/src/fn_maps.cpp +3 -3
- data/ext/libsass/src/fn_miscs.cpp +34 -46
- data/ext/libsass/src/fn_numbers.cpp +20 -13
- data/ext/libsass/src/fn_selectors.cpp +98 -128
- data/ext/libsass/src/fn_strings.cpp +47 -33
- data/ext/libsass/src/fn_utils.cpp +31 -29
- data/ext/libsass/src/fn_utils.hpp +17 -11
- data/ext/libsass/src/inspect.cpp +186 -148
- data/ext/libsass/src/inspect.hpp +31 -29
- data/ext/libsass/src/lexer.cpp +20 -82
- data/ext/libsass/src/lexer.hpp +5 -16
- data/ext/libsass/src/listize.cpp +23 -37
- data/ext/libsass/src/listize.hpp +8 -9
- data/ext/libsass/src/mapping.hpp +1 -0
- data/ext/libsass/src/memory/allocator.cpp +48 -0
- data/ext/libsass/src/memory/allocator.hpp +138 -0
- data/ext/libsass/src/memory/config.hpp +20 -0
- data/ext/libsass/src/memory/memory_pool.hpp +186 -0
- data/ext/libsass/src/memory/{SharedPtr.cpp → shared_ptr.cpp} +2 -2
- data/ext/libsass/src/memory/{SharedPtr.hpp → shared_ptr.hpp} +55 -9
- data/ext/libsass/src/memory.hpp +12 -0
- data/ext/libsass/src/operation.hpp +71 -61
- data/ext/libsass/src/operators.cpp +19 -18
- data/ext/libsass/src/operators.hpp +11 -11
- data/ext/libsass/src/ordered_map.hpp +112 -0
- data/ext/libsass/src/output.cpp +45 -64
- data/ext/libsass/src/output.hpp +6 -6
- data/ext/libsass/src/parser.cpp +512 -700
- data/ext/libsass/src/parser.hpp +89 -97
- data/ext/libsass/src/parser_selectors.cpp +189 -0
- data/ext/libsass/src/permutate.hpp +164 -0
- data/ext/libsass/src/plugins.cpp +7 -7
- data/ext/libsass/src/plugins.hpp +8 -8
- data/ext/libsass/src/position.cpp +7 -26
- data/ext/libsass/src/position.hpp +44 -21
- data/ext/libsass/src/prelexer.cpp +6 -6
- data/ext/libsass/src/remove_placeholders.cpp +55 -56
- data/ext/libsass/src/remove_placeholders.hpp +21 -18
- data/ext/libsass/src/sass.cpp +16 -15
- data/ext/libsass/src/sass.hpp +10 -5
- data/ext/libsass/src/sass2scss.cpp +4 -4
- data/ext/libsass/src/sass_context.cpp +91 -122
- data/ext/libsass/src/sass_context.hpp +2 -2
- data/ext/libsass/src/sass_functions.cpp +1 -1
- data/ext/libsass/src/sass_values.cpp +8 -11
- data/ext/libsass/src/settings.hpp +19 -0
- data/ext/libsass/src/source.cpp +69 -0
- data/ext/libsass/src/source.hpp +95 -0
- data/ext/libsass/src/source_data.hpp +32 -0
- data/ext/libsass/src/source_map.cpp +22 -18
- data/ext/libsass/src/source_map.hpp +12 -9
- data/ext/libsass/src/stylesheet.cpp +22 -0
- data/ext/libsass/src/stylesheet.hpp +57 -0
- data/ext/libsass/src/to_value.cpp +2 -2
- data/ext/libsass/src/to_value.hpp +1 -1
- data/ext/libsass/src/units.cpp +24 -22
- data/ext/libsass/src/units.hpp +8 -8
- data/ext/libsass/src/utf8_string.cpp +9 -10
- data/ext/libsass/src/utf8_string.hpp +7 -6
- data/ext/libsass/src/util.cpp +48 -50
- data/ext/libsass/src/util.hpp +20 -21
- data/ext/libsass/src/util_string.cpp +111 -61
- data/ext/libsass/src/util_string.hpp +62 -8
- data/ext/libsass/src/values.cpp +12 -12
- data/lib/sassc/engine.rb +5 -3
- data/lib/sassc/functions_handler.rb +8 -8
- data/lib/sassc/native.rb +4 -6
- data/lib/sassc/script.rb +4 -4
- data/lib/sassc/version.rb +1 -1
- data/test/functions_test.rb +18 -1
- data/test/native_test.rb +4 -4
- metadata +29 -15
- data/ext/libsass/src/extend.cpp +0 -2132
- data/ext/libsass/src/extend.hpp +0 -86
- data/ext/libsass/src/node.cpp +0 -322
- data/ext/libsass/src/node.hpp +0 -118
- data/ext/libsass/src/paths.hpp +0 -71
- data/ext/libsass/src/sass_util.cpp +0 -152
- data/ext/libsass/src/sass_util.hpp +0 -256
- data/ext/libsass/src/subset_map.cpp +0 -58
- data/ext/libsass/src/subset_map.hpp +0 -76
- data/lib/sassc/native/lib_c.rb +0 -21
@@ -1,54 +1,26 @@
|
|
1
|
+
// sass.hpp must go before all system headers to get the
|
2
|
+
// __EXTENSIONS__ fix on Solaris.
|
1
3
|
#include "sass.hpp"
|
4
|
+
|
2
5
|
#include "ast.hpp"
|
3
|
-
#include "
|
4
|
-
#include "
|
5
|
-
#include "eval.hpp"
|
6
|
-
#include "extend.hpp"
|
7
|
-
#include "emitter.hpp"
|
8
|
-
#include "color_maps.hpp"
|
9
|
-
#include "ast_fwd_decl.hpp"
|
10
|
-
#include "ast_selectors.hpp"
|
11
|
-
#include <array>
|
12
|
-
#include <set>
|
13
|
-
#include <iomanip>
|
14
|
-
#include <iostream>
|
15
|
-
#include <algorithm>
|
16
|
-
#include <functional>
|
17
|
-
#include <cctype>
|
18
|
-
#include <locale>
|
6
|
+
#include "permutate.hpp"
|
7
|
+
#include "util_string.hpp"
|
19
8
|
|
20
9
|
namespace Sass {
|
21
10
|
|
22
11
|
/////////////////////////////////////////////////////////////////////////
|
23
12
|
/////////////////////////////////////////////////////////////////////////
|
24
13
|
|
25
|
-
Selector::Selector(
|
14
|
+
Selector::Selector(SourceSpan pstate)
|
26
15
|
: Expression(pstate),
|
27
|
-
has_line_feed_(false),
|
28
|
-
has_line_break_(false),
|
29
|
-
is_optional_(false),
|
30
|
-
media_block_(0),
|
31
16
|
hash_(0)
|
32
17
|
{ concrete_type(SELECTOR); }
|
33
18
|
|
34
19
|
Selector::Selector(const Selector* ptr)
|
35
20
|
: Expression(ptr),
|
36
|
-
has_line_feed_(ptr->has_line_feed_),
|
37
|
-
has_line_break_(ptr->has_line_break_),
|
38
|
-
is_optional_(ptr->is_optional_),
|
39
|
-
media_block_(ptr->media_block_),
|
40
21
|
hash_(ptr->hash_)
|
41
22
|
{ concrete_type(SELECTOR); }
|
42
23
|
|
43
|
-
void Selector::set_media_block(Media_Block* mb)
|
44
|
-
{
|
45
|
-
media_block(mb);
|
46
|
-
}
|
47
|
-
|
48
|
-
bool Selector::has_parent_ref() const
|
49
|
-
{
|
50
|
-
return false;
|
51
|
-
}
|
52
24
|
|
53
25
|
bool Selector::has_real_parent_ref() const
|
54
26
|
{
|
@@ -58,18 +30,16 @@ namespace Sass {
|
|
58
30
|
/////////////////////////////////////////////////////////////////////////
|
59
31
|
/////////////////////////////////////////////////////////////////////////
|
60
32
|
|
61
|
-
Selector_Schema::Selector_Schema(
|
33
|
+
Selector_Schema::Selector_Schema(SourceSpan pstate, String_Obj c)
|
62
34
|
: AST_Node(pstate),
|
63
35
|
contents_(c),
|
64
36
|
connect_parent_(true),
|
65
|
-
media_block_(NULL),
|
66
37
|
hash_(0)
|
67
38
|
{ }
|
68
39
|
Selector_Schema::Selector_Schema(const Selector_Schema* ptr)
|
69
40
|
: AST_Node(ptr),
|
70
41
|
contents_(ptr->contents_),
|
71
42
|
connect_parent_(ptr->connect_parent_),
|
72
|
-
media_block_(ptr->media_block_),
|
73
43
|
hash_(ptr->hash_)
|
74
44
|
{ }
|
75
45
|
|
@@ -85,181 +55,150 @@ namespace Sass {
|
|
85
55
|
return hash_;
|
86
56
|
}
|
87
57
|
|
88
|
-
bool Selector_Schema::has_parent_ref() const
|
89
|
-
{
|
90
|
-
if (String_Schema_Obj schema = Cast<String_Schema>(contents())) {
|
91
|
-
if (schema->empty()) return false;
|
92
|
-
const auto& first = *schema->at(0);
|
93
|
-
return typeid(first) == typeid(Parent_Selector);
|
94
|
-
}
|
95
|
-
return false;
|
96
|
-
}
|
97
|
-
|
98
58
|
bool Selector_Schema::has_real_parent_ref() const
|
99
59
|
{
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
60
|
+
// Note: disabled since it does not seem to do anything?
|
61
|
+
// if (String_Schema_Obj schema = Cast<String_Schema>(contents())) {
|
62
|
+
// if (schema->empty()) return false;
|
63
|
+
// const auto first = schema->first();
|
64
|
+
// return Cast<Parent_Reference>(first);
|
65
|
+
// }
|
105
66
|
return false;
|
106
67
|
}
|
107
68
|
|
108
69
|
/////////////////////////////////////////////////////////////////////////
|
109
70
|
/////////////////////////////////////////////////////////////////////////
|
110
71
|
|
111
|
-
|
72
|
+
SimpleSelector::SimpleSelector(SourceSpan pstate, sass::string n)
|
112
73
|
: Selector(pstate), ns_(""), name_(n), has_ns_(false)
|
113
74
|
{
|
114
75
|
size_t pos = n.find('|');
|
115
76
|
// found some namespace
|
116
|
-
if (pos !=
|
77
|
+
if (pos != sass::string::npos) {
|
117
78
|
has_ns_ = true;
|
118
79
|
ns_ = n.substr(0, pos);
|
119
80
|
name_ = n.substr(pos + 1);
|
120
81
|
}
|
121
82
|
}
|
122
|
-
|
83
|
+
SimpleSelector::SimpleSelector(const SimpleSelector* ptr)
|
123
84
|
: Selector(ptr),
|
124
85
|
ns_(ptr->ns_),
|
125
86
|
name_(ptr->name_),
|
126
87
|
has_ns_(ptr->has_ns_)
|
127
88
|
{ }
|
128
89
|
|
129
|
-
|
90
|
+
sass::string SimpleSelector::ns_name() const
|
130
91
|
{
|
131
|
-
|
132
|
-
|
133
|
-
name += ns_ + "|";
|
134
|
-
return name + name_;
|
92
|
+
if (!has_ns_) return name_;
|
93
|
+
else return ns_ + "|" + name_;
|
135
94
|
}
|
136
95
|
|
137
|
-
size_t
|
96
|
+
size_t SimpleSelector::hash() const
|
138
97
|
{
|
139
98
|
if (hash_ == 0) {
|
140
|
-
hash_combine(hash_,
|
141
|
-
hash_combine(hash_,
|
142
|
-
|
143
|
-
if (has_ns_) hash_combine(hash_,
|
99
|
+
hash_combine(hash_, name());
|
100
|
+
hash_combine(hash_, (int)SELECTOR);
|
101
|
+
hash_combine(hash_, (int)simple_type());
|
102
|
+
if (has_ns_) hash_combine(hash_, ns());
|
144
103
|
}
|
145
104
|
return hash_;
|
146
105
|
}
|
147
106
|
|
148
|
-
bool
|
107
|
+
bool SimpleSelector::empty() const {
|
149
108
|
return ns().empty() && name().empty();
|
150
109
|
}
|
151
110
|
|
152
111
|
// namespace compare functions
|
153
|
-
bool
|
112
|
+
bool SimpleSelector::is_ns_eq(const SimpleSelector& r) const
|
154
113
|
{
|
155
114
|
return has_ns_ == r.has_ns_ && ns_ == r.ns_;
|
156
115
|
}
|
157
116
|
|
158
117
|
// namespace query functions
|
159
|
-
bool
|
118
|
+
bool SimpleSelector::is_universal_ns() const
|
160
119
|
{
|
161
120
|
return has_ns_ && ns_ == "*";
|
162
121
|
}
|
163
122
|
|
164
|
-
bool
|
123
|
+
bool SimpleSelector::is_empty_ns() const
|
165
124
|
{
|
166
125
|
return !has_ns_ || ns_ == "";
|
167
126
|
}
|
168
127
|
|
169
|
-
bool
|
128
|
+
bool SimpleSelector::has_empty_ns() const
|
170
129
|
{
|
171
130
|
return has_ns_ && ns_ == "";
|
172
131
|
}
|
173
132
|
|
174
|
-
bool
|
133
|
+
bool SimpleSelector::has_qualified_ns() const
|
175
134
|
{
|
176
135
|
return has_ns_ && ns_ != "" && ns_ != "*";
|
177
136
|
}
|
178
137
|
|
179
138
|
// name query functions
|
180
|
-
bool
|
139
|
+
bool SimpleSelector::is_universal() const
|
181
140
|
{
|
182
141
|
return name_ == "*";
|
183
142
|
}
|
184
143
|
|
185
|
-
bool
|
144
|
+
bool SimpleSelector::has_placeholder()
|
186
145
|
{
|
187
146
|
return false;
|
188
147
|
}
|
189
148
|
|
190
|
-
bool
|
191
|
-
{
|
192
|
-
return false;
|
193
|
-
};
|
194
|
-
|
195
|
-
bool Simple_Selector::has_real_parent_ref() const
|
149
|
+
bool SimpleSelector::has_real_parent_ref() const
|
196
150
|
{
|
197
151
|
return false;
|
198
152
|
};
|
199
153
|
|
200
|
-
bool
|
154
|
+
bool SimpleSelector::is_pseudo_element() const
|
201
155
|
{
|
202
156
|
return false;
|
203
157
|
}
|
204
158
|
|
205
|
-
|
159
|
+
CompoundSelectorObj SimpleSelector::wrapInCompound()
|
206
160
|
{
|
207
|
-
|
161
|
+
CompoundSelectorObj selector =
|
162
|
+
SASS_MEMORY_NEW(CompoundSelector, pstate());
|
163
|
+
selector->append(this);
|
164
|
+
return selector;
|
208
165
|
}
|
209
|
-
|
210
|
-
/////////////////////////////////////////////////////////////////////////
|
211
|
-
/////////////////////////////////////////////////////////////////////////
|
212
|
-
|
213
|
-
Parent_Selector::Parent_Selector(ParserState pstate, bool r)
|
214
|
-
: Simple_Selector(pstate, "&"), real_(r)
|
215
|
-
{ simple_type(PARENT_SEL); }
|
216
|
-
Parent_Selector::Parent_Selector(const Parent_Selector* ptr)
|
217
|
-
: Simple_Selector(ptr), real_(ptr->real_)
|
218
|
-
{ simple_type(PARENT_SEL); }
|
219
|
-
|
220
|
-
bool Parent_Selector::has_parent_ref() const
|
221
|
-
{
|
222
|
-
return true;
|
223
|
-
};
|
224
|
-
|
225
|
-
bool Parent_Selector::has_real_parent_ref() const
|
166
|
+
ComplexSelectorObj SimpleSelector::wrapInComplex()
|
226
167
|
{
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
{
|
232
|
-
return 0;
|
168
|
+
ComplexSelectorObj selector =
|
169
|
+
SASS_MEMORY_NEW(ComplexSelector, pstate());
|
170
|
+
selector->append(wrapInCompound());
|
171
|
+
return selector;
|
233
172
|
}
|
234
173
|
|
235
174
|
/////////////////////////////////////////////////////////////////////////
|
236
175
|
/////////////////////////////////////////////////////////////////////////
|
237
176
|
|
238
|
-
|
239
|
-
:
|
177
|
+
PlaceholderSelector::PlaceholderSelector(SourceSpan pstate, sass::string n)
|
178
|
+
: SimpleSelector(pstate, n)
|
240
179
|
{ simple_type(PLACEHOLDER_SEL); }
|
241
|
-
|
242
|
-
:
|
180
|
+
PlaceholderSelector::PlaceholderSelector(const PlaceholderSelector* ptr)
|
181
|
+
: SimpleSelector(ptr)
|
243
182
|
{ simple_type(PLACEHOLDER_SEL); }
|
244
|
-
unsigned long
|
183
|
+
unsigned long PlaceholderSelector::specificity() const
|
245
184
|
{
|
246
185
|
return Constants::Specificity_Base;
|
247
186
|
}
|
248
|
-
bool
|
187
|
+
bool PlaceholderSelector::has_placeholder() {
|
249
188
|
return true;
|
250
189
|
}
|
251
190
|
|
252
191
|
/////////////////////////////////////////////////////////////////////////
|
253
192
|
/////////////////////////////////////////////////////////////////////////
|
254
193
|
|
255
|
-
|
256
|
-
:
|
194
|
+
TypeSelector::TypeSelector(SourceSpan pstate, sass::string n)
|
195
|
+
: SimpleSelector(pstate, n)
|
257
196
|
{ simple_type(TYPE_SEL); }
|
258
|
-
|
259
|
-
:
|
197
|
+
TypeSelector::TypeSelector(const TypeSelector* ptr)
|
198
|
+
: SimpleSelector(ptr)
|
260
199
|
{ simple_type(TYPE_SEL); }
|
261
200
|
|
262
|
-
unsigned long
|
201
|
+
unsigned long TypeSelector::specificity() const
|
263
202
|
{
|
264
203
|
if (name() == "*") return 0;
|
265
204
|
else return Constants::Specificity_Element;
|
@@ -268,14 +207,14 @@ namespace Sass {
|
|
268
207
|
/////////////////////////////////////////////////////////////////////////
|
269
208
|
/////////////////////////////////////////////////////////////////////////
|
270
209
|
|
271
|
-
|
272
|
-
:
|
210
|
+
ClassSelector::ClassSelector(SourceSpan pstate, sass::string n)
|
211
|
+
: SimpleSelector(pstate, n)
|
273
212
|
{ simple_type(CLASS_SEL); }
|
274
|
-
|
275
|
-
:
|
213
|
+
ClassSelector::ClassSelector(const ClassSelector* ptr)
|
214
|
+
: SimpleSelector(ptr)
|
276
215
|
{ simple_type(CLASS_SEL); }
|
277
216
|
|
278
|
-
unsigned long
|
217
|
+
unsigned long ClassSelector::specificity() const
|
279
218
|
{
|
280
219
|
return Constants::Specificity_Class;
|
281
220
|
}
|
@@ -283,14 +222,14 @@ namespace Sass {
|
|
283
222
|
/////////////////////////////////////////////////////////////////////////
|
284
223
|
/////////////////////////////////////////////////////////////////////////
|
285
224
|
|
286
|
-
|
287
|
-
:
|
225
|
+
IDSelector::IDSelector(SourceSpan pstate, sass::string n)
|
226
|
+
: SimpleSelector(pstate, n)
|
288
227
|
{ simple_type(ID_SEL); }
|
289
|
-
|
290
|
-
:
|
228
|
+
IDSelector::IDSelector(const IDSelector* ptr)
|
229
|
+
: SimpleSelector(ptr)
|
291
230
|
{ simple_type(ID_SEL); }
|
292
231
|
|
293
|
-
unsigned long
|
232
|
+
unsigned long IDSelector::specificity() const
|
294
233
|
{
|
295
234
|
return Constants::Specificity_ID;
|
296
235
|
}
|
@@ -298,27 +237,27 @@ namespace Sass {
|
|
298
237
|
/////////////////////////////////////////////////////////////////////////
|
299
238
|
/////////////////////////////////////////////////////////////////////////
|
300
239
|
|
301
|
-
|
302
|
-
:
|
240
|
+
AttributeSelector::AttributeSelector(SourceSpan pstate, sass::string n, sass::string m, String_Obj v, char o)
|
241
|
+
: SimpleSelector(pstate, n), matcher_(m), value_(v), modifier_(o)
|
303
242
|
{ simple_type(ATTRIBUTE_SEL); }
|
304
|
-
|
305
|
-
:
|
243
|
+
AttributeSelector::AttributeSelector(const AttributeSelector* ptr)
|
244
|
+
: SimpleSelector(ptr),
|
306
245
|
matcher_(ptr->matcher_),
|
307
246
|
value_(ptr->value_),
|
308
247
|
modifier_(ptr->modifier_)
|
309
248
|
{ simple_type(ATTRIBUTE_SEL); }
|
310
249
|
|
311
|
-
size_t
|
250
|
+
size_t AttributeSelector::hash() const
|
312
251
|
{
|
313
252
|
if (hash_ == 0) {
|
314
|
-
hash_combine(hash_,
|
315
|
-
hash_combine(hash_, std::hash<
|
253
|
+
hash_combine(hash_, SimpleSelector::hash());
|
254
|
+
hash_combine(hash_, std::hash<sass::string>()(matcher()));
|
316
255
|
if (value_) hash_combine(hash_, value_->hash());
|
317
256
|
}
|
318
257
|
return hash_;
|
319
258
|
}
|
320
259
|
|
321
|
-
unsigned long
|
260
|
+
unsigned long AttributeSelector::specificity() const
|
322
261
|
{
|
323
262
|
return Constants::Specificity_Attr;
|
324
263
|
}
|
@@ -326,11 +265,21 @@ namespace Sass {
|
|
326
265
|
/////////////////////////////////////////////////////////////////////////
|
327
266
|
/////////////////////////////////////////////////////////////////////////
|
328
267
|
|
329
|
-
|
330
|
-
:
|
268
|
+
PseudoSelector::PseudoSelector(SourceSpan pstate, sass::string name, bool element)
|
269
|
+
: SimpleSelector(pstate, name),
|
270
|
+
normalized_(Util::unvendor(name)),
|
271
|
+
argument_({}),
|
272
|
+
selector_({}),
|
273
|
+
isSyntacticClass_(!element),
|
274
|
+
isClass_(!element && !isFakePseudoElement(normalized_))
|
331
275
|
{ simple_type(PSEUDO_SEL); }
|
332
|
-
|
333
|
-
:
|
276
|
+
PseudoSelector::PseudoSelector(const PseudoSelector* ptr)
|
277
|
+
: SimpleSelector(ptr),
|
278
|
+
normalized_(ptr->normalized()),
|
279
|
+
argument_(ptr->argument()),
|
280
|
+
selector_(ptr->selector()),
|
281
|
+
isSyntacticClass_(ptr->isSyntacticClass()),
|
282
|
+
isClass_(ptr->isClass())
|
334
283
|
{ simple_type(PSEUDO_SEL); }
|
335
284
|
|
336
285
|
// A pseudo-element is made of two colons (::) followed by the name.
|
@@ -341,1135 +290,754 @@ namespace Sass {
|
|
341
290
|
// in CSS levels 1 and 2 (namely, :first-line, :first-letter, :before and
|
342
291
|
// :after). This compatibility is not allowed for the new pseudo-elements
|
343
292
|
// introduced in this specification.
|
344
|
-
bool
|
293
|
+
bool PseudoSelector::is_pseudo_element() const
|
345
294
|
{
|
346
|
-
return (
|
347
|
-
|| is_pseudo_class_element(name_);
|
295
|
+
return isElement();
|
348
296
|
}
|
349
297
|
|
350
|
-
size_t
|
298
|
+
size_t PseudoSelector::hash() const
|
351
299
|
{
|
352
300
|
if (hash_ == 0) {
|
353
|
-
hash_combine(hash_,
|
354
|
-
if (
|
301
|
+
hash_combine(hash_, SimpleSelector::hash());
|
302
|
+
if (selector_) hash_combine(hash_, selector_->hash());
|
303
|
+
if (argument_) hash_combine(hash_, argument_->hash());
|
355
304
|
}
|
356
305
|
return hash_;
|
357
306
|
}
|
358
307
|
|
359
|
-
unsigned long
|
308
|
+
unsigned long PseudoSelector::specificity() const
|
360
309
|
{
|
361
310
|
if (is_pseudo_element())
|
362
311
|
return Constants::Specificity_Element;
|
363
312
|
return Constants::Specificity_Pseudo;
|
364
313
|
}
|
365
314
|
|
366
|
-
|
367
|
-
/////////////////////////////////////////////////////////////////////////
|
368
|
-
|
369
|
-
Wrapped_Selector::Wrapped_Selector(ParserState pstate, std::string n, Selector_List_Obj sel)
|
370
|
-
: Simple_Selector(pstate, n), selector_(sel)
|
371
|
-
{ simple_type(WRAPPED_SEL); }
|
372
|
-
Wrapped_Selector::Wrapped_Selector(const Wrapped_Selector* ptr)
|
373
|
-
: Simple_Selector(ptr), selector_(ptr->selector_)
|
374
|
-
{ simple_type(WRAPPED_SEL); }
|
375
|
-
|
376
|
-
bool Wrapped_Selector::is_superselector_of(const Wrapped_Selector* sub) const
|
315
|
+
PseudoSelectorObj PseudoSelector::withSelector(SelectorListObj selector)
|
377
316
|
{
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
if (Selector_List_Obj lhs_list = Cast<Selector_List>(selector())) {
|
382
|
-
return lhs_list->is_superselector_of(rhs_list);
|
383
|
-
}
|
384
|
-
}
|
385
|
-
coreError("is_superselector expected a Selector_List", sub->pstate());
|
386
|
-
return false;
|
317
|
+
PseudoSelectorObj pseudo = SASS_MEMORY_COPY(this);
|
318
|
+
pseudo->selector(selector);
|
319
|
+
return pseudo;
|
387
320
|
}
|
388
321
|
|
389
|
-
|
390
|
-
// other, but the negation itself does not count as a pseudo-class.
|
391
|
-
|
392
|
-
void Wrapped_Selector::cloneChildren()
|
322
|
+
bool PseudoSelector::empty() const
|
393
323
|
{
|
394
|
-
selector
|
324
|
+
// Only considered empty if selector is
|
325
|
+
// available but has no items in it.
|
326
|
+
return selector() && selector()->empty();
|
395
327
|
}
|
396
328
|
|
397
|
-
|
329
|
+
void PseudoSelector::cloneChildren()
|
398
330
|
{
|
399
|
-
if (
|
400
|
-
|
401
|
-
if (selector_) hash_combine(hash_, selector_->hash());
|
402
|
-
}
|
403
|
-
return hash_;
|
404
|
-
}
|
405
|
-
|
406
|
-
bool Wrapped_Selector::has_parent_ref() const {
|
407
|
-
if (!selector()) return false;
|
408
|
-
return selector()->has_parent_ref();
|
331
|
+
if (selector().isNull()) selector({});
|
332
|
+
else selector(SASS_MEMORY_CLONE(selector()));
|
409
333
|
}
|
410
334
|
|
411
|
-
bool
|
335
|
+
bool PseudoSelector::has_real_parent_ref() const {
|
412
336
|
if (!selector()) return false;
|
413
337
|
return selector()->has_real_parent_ref();
|
414
338
|
}
|
415
339
|
|
416
|
-
unsigned long Wrapped_Selector::specificity() const
|
417
|
-
{
|
418
|
-
return selector_ ? selector_->specificity() : 0;
|
419
|
-
}
|
420
|
-
|
421
|
-
bool Wrapped_Selector::find ( bool (*f)(AST_Node_Obj) )
|
422
|
-
{
|
423
|
-
// check children first
|
424
|
-
if (selector_) {
|
425
|
-
if (selector_->find(f)) return true;
|
426
|
-
}
|
427
|
-
// execute last
|
428
|
-
return f(this);
|
429
|
-
}
|
430
|
-
|
431
340
|
/////////////////////////////////////////////////////////////////////////
|
432
341
|
/////////////////////////////////////////////////////////////////////////
|
433
342
|
|
434
|
-
|
343
|
+
SelectorList::SelectorList(SourceSpan pstate, size_t s)
|
435
344
|
: Selector(pstate),
|
436
|
-
Vectorized<
|
437
|
-
|
438
|
-
has_parent_reference_(false)
|
345
|
+
Vectorized<ComplexSelectorObj>(s),
|
346
|
+
is_optional_(false)
|
439
347
|
{ }
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
extended_(ptr->extended_),
|
445
|
-
has_parent_reference_(ptr->has_parent_reference_)
|
348
|
+
SelectorList::SelectorList(const SelectorList* ptr)
|
349
|
+
: Selector(ptr),
|
350
|
+
Vectorized<ComplexSelectorObj>(*ptr),
|
351
|
+
is_optional_(ptr->is_optional_)
|
446
352
|
{ }
|
447
353
|
|
448
|
-
|
449
|
-
for (size_t i = 0, L = length(); i < L; ++i) {
|
450
|
-
if ((*this)[i]->has_placeholder()) return true;
|
451
|
-
}
|
452
|
-
return false;
|
453
|
-
};
|
454
|
-
|
455
|
-
void Compound_Selector::cloneChildren()
|
354
|
+
size_t SelectorList::hash() const
|
456
355
|
{
|
457
|
-
|
458
|
-
|
356
|
+
if (Selector::hash_ == 0) {
|
357
|
+
hash_combine(Selector::hash_, Vectorized::hash());
|
459
358
|
}
|
359
|
+
return Selector::hash_;
|
460
360
|
}
|
461
361
|
|
462
|
-
bool
|
362
|
+
bool SelectorList::has_real_parent_ref() const
|
463
363
|
{
|
464
|
-
|
465
|
-
|
466
|
-
if (sel->find(f)) return true;
|
364
|
+
for (ComplexSelectorObj s : elements()) {
|
365
|
+
if (s && s->has_real_parent_ref()) return true;
|
467
366
|
}
|
468
|
-
|
469
|
-
return f(this);
|
367
|
+
return false;
|
470
368
|
}
|
471
369
|
|
472
|
-
|
370
|
+
void SelectorList::cloneChildren()
|
473
371
|
{
|
474
|
-
for (
|
475
|
-
|
372
|
+
for (size_t i = 0, l = length(); i < l; i++) {
|
373
|
+
at(i) = SASS_MEMORY_CLONE(at(i));
|
476
374
|
}
|
477
|
-
return false;
|
478
375
|
}
|
479
376
|
|
480
|
-
|
377
|
+
unsigned long SelectorList::specificity() const
|
481
378
|
{
|
482
|
-
|
483
|
-
if (s && s->has_real_parent_ref()) return true;
|
484
|
-
}
|
485
|
-
return false;
|
379
|
+
return 0;
|
486
380
|
}
|
487
381
|
|
488
|
-
bool
|
382
|
+
bool SelectorList::isInvisible() const
|
489
383
|
{
|
490
|
-
|
491
|
-
|
384
|
+
if (length() == 0) return true;
|
385
|
+
for (size_t i = 0; i < length(); i += 1) {
|
386
|
+
if (get(i)->isInvisible()) return true;
|
492
387
|
}
|
493
388
|
return false;
|
494
389
|
}
|
495
390
|
|
496
|
-
|
391
|
+
/////////////////////////////////////////////////////////////////////////
|
392
|
+
/////////////////////////////////////////////////////////////////////////
|
393
|
+
|
394
|
+
ComplexSelector::ComplexSelector(SourceSpan pstate)
|
395
|
+
: Selector(pstate),
|
396
|
+
Vectorized<SelectorComponentObj>(),
|
397
|
+
chroots_(false),
|
398
|
+
hasPreLineFeed_(false)
|
497
399
|
{
|
498
|
-
if (rhs->head()) return is_superselector_of(rhs->head(), wrapped);
|
499
|
-
return false;
|
500
400
|
}
|
501
|
-
|
502
|
-
|
401
|
+
ComplexSelector::ComplexSelector(const ComplexSelector* ptr)
|
402
|
+
: Selector(ptr),
|
403
|
+
Vectorized<SelectorComponentObj>(ptr->elements()),
|
404
|
+
chroots_(ptr->chroots()),
|
405
|
+
hasPreLineFeed_(ptr->hasPreLineFeed())
|
503
406
|
{
|
504
|
-
|
505
|
-
{
|
506
|
-
std::array<std::set<std::string>, 2> pseudosets;
|
507
|
-
std::array<const Compound_Selector*, 2> compounds = {{this, rhs}};
|
508
|
-
for (int i = 0; i < 2; ++i) {
|
509
|
-
for (const Simple_Selector_Obj& el : compounds[i]->elements()) {
|
510
|
-
if (el->is_pseudo_element()) {
|
511
|
-
std::string pseudo(el->to_string());
|
512
|
-
// strip off colons to ensure :after matches ::after since ruby sass is forgiving
|
513
|
-
pseudosets[i].insert(pseudo.substr(pseudo.find_first_not_of(":")));
|
514
|
-
}
|
515
|
-
}
|
516
|
-
}
|
517
|
-
if (pseudosets[0] != pseudosets[1]) return false;
|
518
|
-
}
|
519
|
-
|
520
|
-
{
|
521
|
-
const Simple_Selector* lbase = this->base();
|
522
|
-
const Simple_Selector* rbase = rhs->base();
|
523
|
-
if (lbase && rbase) {
|
524
|
-
return *lbase == *rbase &&
|
525
|
-
contains_all(std::unordered_set<const Simple_Selector*, HashPtr, ComparePtrs>(rhs->begin(), rhs->end()),
|
526
|
-
std::unordered_set<const Simple_Selector*, HashPtr, ComparePtrs>(this->begin(), this->end()));
|
527
|
-
}
|
528
|
-
}
|
529
|
-
|
530
|
-
std::unordered_set<const Selector*, HashPtr, ComparePtrs> lset;
|
531
|
-
for (size_t i = 0, iL = length(); i < iL; ++i)
|
532
|
-
{
|
533
|
-
const Selector* wlhs = (*this)[i].ptr();
|
534
|
-
// very special case for wrapped matches selector
|
535
|
-
if (const Wrapped_Selector* wrapped = Cast<Wrapped_Selector>(wlhs)) {
|
536
|
-
if (wrapped->name() == ":not") {
|
537
|
-
if (Selector_List_Obj not_list = Cast<Selector_List>(wrapped->selector())) {
|
538
|
-
if (not_list->is_superselector_of(rhs, wrapped->name())) return false;
|
539
|
-
} else {
|
540
|
-
throw std::runtime_error("wrapped not selector is not a list");
|
541
|
-
}
|
542
|
-
}
|
543
|
-
if (wrapped->name() == ":matches" || wrapped->name() == ":-moz-any") {
|
544
|
-
wlhs = wrapped->selector();
|
545
|
-
if (Selector_List_Obj list = Cast<Selector_List>(wrapped->selector())) {
|
546
|
-
if (const Compound_Selector* comp = Cast<Compound_Selector>(rhs)) {
|
547
|
-
if (!wrapping.empty() && wrapping != wrapped->name()) return false;
|
548
|
-
if (wrapping.empty() || wrapping != wrapped->name()) {;
|
549
|
-
if (list->is_superselector_of(comp, wrapped->name())) return true;
|
550
|
-
}
|
551
|
-
}
|
552
|
-
}
|
553
|
-
}
|
554
|
-
Simple_Selector* rhs_sel = nullptr;
|
555
|
-
if (rhs->elements().size() > i) rhs_sel = (*rhs)[i];
|
556
|
-
if (Wrapped_Selector* wrapped_r = Cast<Wrapped_Selector>(rhs_sel)) {
|
557
|
-
if (wrapped->name() == wrapped_r->name()) {
|
558
|
-
if (wrapped->is_superselector_of(wrapped_r)) {
|
559
|
-
continue;
|
560
|
-
}}
|
561
|
-
}
|
562
|
-
}
|
563
|
-
lset.insert(wlhs);
|
564
|
-
}
|
407
|
+
}
|
565
408
|
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
{
|
571
|
-
Selector_Obj r = (*rhs)[n];
|
572
|
-
if (Wrapped_Selector_Obj wrapped = Cast<Wrapped_Selector>(r)) {
|
573
|
-
if (wrapped->name() == ":not") {
|
574
|
-
if (Selector_List_Obj ls = Cast<Selector_List>(wrapped->selector())) {
|
575
|
-
ls->remove_parent_selectors(); // unverified
|
576
|
-
if (is_superselector_of(ls, wrapped->name())) return false;
|
577
|
-
}
|
578
|
-
}
|
579
|
-
if (wrapped->name() == ":matches" || wrapped->name() == ":-moz-any") {
|
580
|
-
if (!wrapping.empty()) {
|
581
|
-
if (wrapping != wrapped->name()) return false;
|
582
|
-
}
|
583
|
-
if (Selector_List_Obj ls = Cast<Selector_List>(wrapped->selector())) {
|
584
|
-
ls->remove_parent_selectors(); // unverified
|
585
|
-
return (is_superselector_of(ls, wrapped->name()));
|
586
|
-
}
|
587
|
-
}
|
588
|
-
}
|
589
|
-
rset.insert(r);
|
409
|
+
void ComplexSelector::cloneChildren()
|
410
|
+
{
|
411
|
+
for (size_t i = 0, l = length(); i < l; i++) {
|
412
|
+
at(i) = SASS_MEMORY_CLONE(at(i));
|
590
413
|
}
|
591
|
-
|
592
|
-
return contains_all(rset, lset);
|
593
414
|
}
|
594
415
|
|
595
|
-
|
416
|
+
unsigned long ComplexSelector::specificity() const
|
596
417
|
{
|
597
|
-
|
418
|
+
int sum = 0;
|
419
|
+
for (auto component : elements()) {
|
420
|
+
sum += component->specificity();
|
421
|
+
}
|
422
|
+
return sum;
|
598
423
|
}
|
599
424
|
|
600
|
-
|
601
|
-
Complex_Selector_Obj Compound_Selector::to_complex()
|
425
|
+
bool ComplexSelector::isInvisible() const
|
602
426
|
{
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
427
|
+
if (length() == 0) return true;
|
428
|
+
for (size_t i = 0; i < length(); i += 1) {
|
429
|
+
if (CompoundSelectorObj compound = get(i)->getCompound()) {
|
430
|
+
if (compound->isInvisible()) return true;
|
431
|
+
}
|
432
|
+
}
|
433
|
+
return false;
|
609
434
|
}
|
610
435
|
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
return
|
436
|
+
SelectorListObj ComplexSelector::wrapInList()
|
437
|
+
{
|
438
|
+
SelectorListObj selector =
|
439
|
+
SASS_MEMORY_NEW(SelectorList, pstate());
|
440
|
+
selector->append(this);
|
441
|
+
return selector;
|
617
442
|
}
|
618
443
|
|
619
|
-
size_t
|
444
|
+
size_t ComplexSelector::hash() const
|
620
445
|
{
|
621
446
|
if (Selector::hash_ == 0) {
|
622
|
-
hash_combine(Selector::hash_,
|
623
|
-
|
447
|
+
hash_combine(Selector::hash_, Vectorized::hash());
|
448
|
+
// ToDo: this breaks some extend lookup
|
449
|
+
// hash_combine(Selector::hash_, chroots_);
|
624
450
|
}
|
625
451
|
return Selector::hash_;
|
626
452
|
}
|
627
453
|
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
return sum;
|
454
|
+
bool ComplexSelector::has_placeholder() const {
|
455
|
+
for (size_t i = 0, L = length(); i < L; ++i) {
|
456
|
+
if (get(i)->has_placeholder()) return true;
|
457
|
+
}
|
458
|
+
return false;
|
634
459
|
}
|
635
460
|
|
636
|
-
bool
|
461
|
+
bool ComplexSelector::has_real_parent_ref() const
|
637
462
|
{
|
638
|
-
|
639
|
-
|
640
|
-
if (ss->has_placeholder()) return true;
|
463
|
+
for (auto item : elements()) {
|
464
|
+
if (item->has_real_parent_ref()) return true;
|
641
465
|
}
|
642
466
|
return false;
|
643
467
|
}
|
644
468
|
|
645
|
-
|
469
|
+
/////////////////////////////////////////////////////////////////////////
|
470
|
+
/////////////////////////////////////////////////////////////////////////
|
471
|
+
|
472
|
+
SelectorComponent::SelectorComponent(SourceSpan pstate, bool postLineBreak)
|
473
|
+
: Selector(pstate),
|
474
|
+
hasPostLineBreak_(postLineBreak)
|
646
475
|
{
|
647
|
-
return length() == 1 &&
|
648
|
-
Cast<Parent_Selector>((*this)[0]);
|
649
476
|
}
|
650
477
|
|
651
|
-
|
478
|
+
SelectorComponent::SelectorComponent(const SelectorComponent* ptr)
|
479
|
+
: Selector(ptr),
|
480
|
+
hasPostLineBreak_(ptr->hasPostLineBreak())
|
481
|
+
{ }
|
482
|
+
|
483
|
+
void SelectorComponent::cloneChildren()
|
652
484
|
{
|
653
|
-
Vectorized<Simple_Selector_Obj>::append(element);
|
654
|
-
pstate_.offset += element->pstate().offset;
|
655
485
|
}
|
656
486
|
|
657
|
-
|
487
|
+
unsigned long SelectorComponent::specificity() const
|
658
488
|
{
|
659
|
-
|
660
|
-
// result->has_parent_reference(has_parent_reference());
|
661
|
-
|
662
|
-
// not very efficient because it needs to preserve order
|
663
|
-
for (size_t i = 0, L = length(); i < L; ++i)
|
664
|
-
{
|
665
|
-
bool found = false;
|
666
|
-
for (size_t j = 0, M = rhs->length(); j < M; ++j)
|
667
|
-
{
|
668
|
-
if (*get(i) == *rhs->get(j))
|
669
|
-
{
|
670
|
-
found = true;
|
671
|
-
break;
|
672
|
-
}
|
673
|
-
}
|
674
|
-
if (!found) result->append(get(i));
|
675
|
-
}
|
676
|
-
|
677
|
-
return result;
|
489
|
+
return 0;
|
678
490
|
}
|
679
491
|
|
680
|
-
|
492
|
+
// Wrap the compound selector with a complex selector
|
493
|
+
ComplexSelector* SelectorComponent::wrapInComplex()
|
681
494
|
{
|
682
|
-
|
683
|
-
|
684
|
-
|
495
|
+
auto complex = SASS_MEMORY_NEW(ComplexSelector, pstate());
|
496
|
+
complex->append(this);
|
497
|
+
return complex;
|
685
498
|
}
|
686
499
|
|
687
500
|
/////////////////////////////////////////////////////////////////////////
|
688
501
|
/////////////////////////////////////////////////////////////////////////
|
689
502
|
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
String_Obj r)
|
695
|
-
: Selector(pstate),
|
696
|
-
combinator_(c),
|
697
|
-
head_(h), tail_(t),
|
698
|
-
reference_(r)
|
699
|
-
{}
|
700
|
-
Complex_Selector::Complex_Selector(const Complex_Selector* ptr)
|
701
|
-
: Selector(ptr),
|
702
|
-
combinator_(ptr->combinator_),
|
703
|
-
head_(ptr->head_), tail_(ptr->tail_),
|
704
|
-
reference_(ptr->reference_)
|
705
|
-
{}
|
706
|
-
|
707
|
-
bool Complex_Selector::empty() const {
|
708
|
-
return (!tail() || tail()->empty())
|
709
|
-
&& (!head() || head()->empty())
|
710
|
-
&& combinator_ == ANCESTOR_OF;
|
711
|
-
}
|
712
|
-
|
713
|
-
Complex_Selector_Obj Complex_Selector::skip_empty_reference()
|
714
|
-
{
|
715
|
-
if ((!head_ || !head_->length() || head_->is_empty_reference()) &&
|
716
|
-
combinator() == Combinator::ANCESTOR_OF)
|
717
|
-
{
|
718
|
-
if (!tail_) return {};
|
719
|
-
tail_->has_line_feed_ = this->has_line_feed_;
|
720
|
-
// tail_->has_line_break_ = this->has_line_break_;
|
721
|
-
return tail_->skip_empty_reference();
|
722
|
-
}
|
723
|
-
return this;
|
503
|
+
SelectorCombinator::SelectorCombinator(SourceSpan pstate, SelectorCombinator::Combinator combinator, bool postLineBreak)
|
504
|
+
: SelectorComponent(pstate, postLineBreak),
|
505
|
+
combinator_(combinator)
|
506
|
+
{
|
724
507
|
}
|
508
|
+
SelectorCombinator::SelectorCombinator(const SelectorCombinator* ptr)
|
509
|
+
: SelectorComponent(ptr->pstate(), false),
|
510
|
+
combinator_(ptr->combinator())
|
511
|
+
{ }
|
725
512
|
|
726
|
-
|
513
|
+
void SelectorCombinator::cloneChildren()
|
727
514
|
{
|
728
|
-
return (!head() || head()->length() == 0) &&
|
729
|
-
combinator() == Combinator::ANCESTOR_OF;
|
730
515
|
}
|
731
516
|
|
732
|
-
|
517
|
+
unsigned long SelectorCombinator::specificity() const
|
733
518
|
{
|
734
|
-
|
735
|
-
if (head_) {
|
736
|
-
hash_combine(hash_, head_->hash());
|
737
|
-
} else {
|
738
|
-
hash_combine(hash_, std::hash<int>()(SELECTOR));
|
739
|
-
}
|
740
|
-
if (tail_) hash_combine(hash_, tail_->hash());
|
741
|
-
if (combinator_ != ANCESTOR_OF) hash_combine(hash_, std::hash<int>()(combinator_));
|
742
|
-
}
|
743
|
-
return hash_;
|
519
|
+
return 0;
|
744
520
|
}
|
745
521
|
|
746
|
-
|
522
|
+
/////////////////////////////////////////////////////////////////////////
|
523
|
+
/////////////////////////////////////////////////////////////////////////
|
524
|
+
|
525
|
+
CompoundSelector::CompoundSelector(SourceSpan pstate, bool postLineBreak)
|
526
|
+
: SelectorComponent(pstate, postLineBreak),
|
527
|
+
Vectorized<SimpleSelectorObj>(),
|
528
|
+
hasRealParent_(false),
|
529
|
+
extended_(false)
|
747
530
|
{
|
748
|
-
int sum = 0;
|
749
|
-
if (head()) sum += head()->specificity();
|
750
|
-
if (tail()) sum += tail()->specificity();
|
751
|
-
return sum;
|
752
531
|
}
|
532
|
+
CompoundSelector::CompoundSelector(const CompoundSelector* ptr)
|
533
|
+
: SelectorComponent(ptr),
|
534
|
+
Vectorized<SimpleSelectorObj>(*ptr),
|
535
|
+
hasRealParent_(ptr->hasRealParent()),
|
536
|
+
extended_(ptr->extended())
|
537
|
+
{ }
|
753
538
|
|
754
|
-
|
755
|
-
|
756
|
-
if (
|
757
|
-
|
539
|
+
size_t CompoundSelector::hash() const
|
540
|
+
{
|
541
|
+
if (Selector::hash_ == 0) {
|
542
|
+
hash_combine(Selector::hash_, Vectorized::hash());
|
543
|
+
hash_combine(Selector::hash_, hasRealParent_);
|
544
|
+
}
|
545
|
+
return Selector::hash_;
|
758
546
|
}
|
759
547
|
|
760
|
-
bool
|
761
|
-
|
762
|
-
if (
|
548
|
+
bool CompoundSelector::has_real_parent_ref() const
|
549
|
+
{
|
550
|
+
if (hasRealParent()) return true;
|
551
|
+
// ToDo: dart sass has another check?
|
552
|
+
// if (Cast<TypeSelector>(front)) {
|
553
|
+
// if (front->ns() != "") return false;
|
554
|
+
// }
|
555
|
+
for (const SimpleSelector* s : elements()) {
|
556
|
+
if (s && s->has_real_parent_ref()) return true;
|
557
|
+
}
|
763
558
|
return false;
|
764
559
|
}
|
765
560
|
|
766
|
-
|
561
|
+
bool CompoundSelector::has_placeholder() const
|
767
562
|
{
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
ComplexSelectorSet srcs;
|
773
|
-
|
774
|
-
Compound_Selector_Obj pHead = head();
|
775
|
-
Complex_Selector_Obj pTail = tail();
|
776
|
-
|
777
|
-
if (pHead) {
|
778
|
-
const ComplexSelectorSet& headSources = pHead->sources();
|
779
|
-
srcs.insert(headSources.begin(), headSources.end());
|
780
|
-
}
|
781
|
-
|
782
|
-
if (pTail) {
|
783
|
-
const ComplexSelectorSet& tailSources = pTail->sources();
|
784
|
-
srcs.insert(tailSources.begin(), tailSources.end());
|
563
|
+
if (length() == 0) return false;
|
564
|
+
for (SimpleSelectorObj ss : elements()) {
|
565
|
+
if (ss->has_placeholder()) return true;
|
785
566
|
}
|
786
|
-
|
787
|
-
return srcs;
|
567
|
+
return false;
|
788
568
|
}
|
789
569
|
|
790
|
-
void
|
570
|
+
void CompoundSelector::cloneChildren()
|
791
571
|
{
|
792
|
-
|
793
|
-
|
794
|
-
while (pIter) {
|
795
|
-
Compound_Selector* pHead = pIter->head();
|
796
|
-
|
797
|
-
if (pHead) {
|
798
|
-
pHead->mergeSources(sources);
|
799
|
-
}
|
800
|
-
|
801
|
-
pIter = pIter->tail();
|
572
|
+
for (size_t i = 0, l = length(); i < l; i++) {
|
573
|
+
at(i) = SASS_MEMORY_CLONE(at(i));
|
802
574
|
}
|
803
575
|
}
|
804
576
|
|
805
|
-
|
577
|
+
unsigned long CompoundSelector::specificity() const
|
806
578
|
{
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
pHead->clearSources();
|
813
|
-
}
|
579
|
+
int sum = 0;
|
580
|
+
for (size_t i = 0, L = length(); i < L; ++i)
|
581
|
+
{ sum += get(i)->specificity(); }
|
582
|
+
return sum;
|
583
|
+
}
|
814
584
|
|
815
|
-
|
585
|
+
bool CompoundSelector::isInvisible() const
|
586
|
+
{
|
587
|
+
for (size_t i = 0; i < length(); i += 1) {
|
588
|
+
if (!get(i)->isInvisible()) return false;
|
816
589
|
}
|
590
|
+
return true;
|
817
591
|
}
|
818
592
|
|
819
|
-
bool
|
593
|
+
bool CompoundSelector::isSuperselectorOf(const CompoundSelector* sub, sass::string wrapped) const
|
820
594
|
{
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
// execute last
|
825
|
-
return f(this);
|
595
|
+
CompoundSelector* rhs2 = const_cast<CompoundSelector*>(sub);
|
596
|
+
CompoundSelector* lhs2 = const_cast<CompoundSelector*>(this);
|
597
|
+
return compoundIsSuperselector(lhs2, rhs2, {});
|
826
598
|
}
|
827
599
|
|
828
|
-
|
600
|
+
/////////////////////////////////////////////////////////////////////////
|
601
|
+
/////////////////////////////////////////////////////////////////////////
|
602
|
+
|
603
|
+
MediaRule::MediaRule(SourceSpan pstate, Block_Obj block) :
|
604
|
+
ParentStatement(pstate, block),
|
605
|
+
schema_({})
|
829
606
|
{
|
830
|
-
|
831
|
-
(tail() && tail()->has_parent_ref());
|
607
|
+
statement_type(MEDIA);
|
832
608
|
}
|
833
609
|
|
834
|
-
|
610
|
+
MediaRule::MediaRule(const MediaRule* ptr) :
|
611
|
+
ParentStatement(ptr),
|
612
|
+
schema_(ptr->schema_)
|
835
613
|
{
|
836
|
-
|
837
|
-
(tail() && tail()->has_real_parent_ref());
|
614
|
+
statement_type(MEDIA);
|
838
615
|
}
|
839
616
|
|
840
|
-
|
617
|
+
/////////////////////////////////////////////////////////////////////////
|
618
|
+
/////////////////////////////////////////////////////////////////////////
|
619
|
+
|
620
|
+
CssMediaRule::CssMediaRule(SourceSpan pstate, Block_Obj block) :
|
621
|
+
ParentStatement(pstate, block),
|
622
|
+
Vectorized()
|
841
623
|
{
|
842
|
-
|
624
|
+
statement_type(MEDIA);
|
843
625
|
}
|
844
626
|
|
845
|
-
|
627
|
+
CssMediaRule::CssMediaRule(const CssMediaRule* ptr) :
|
628
|
+
ParentStatement(ptr),
|
629
|
+
Vectorized(*ptr)
|
846
630
|
{
|
847
|
-
|
848
|
-
|
849
|
-
if (!lhs->head() || !rhs->head())
|
850
|
-
{ return false; }
|
851
|
-
const Complex_Selector* l_innermost = lhs->last();
|
852
|
-
if (l_innermost->combinator() != Complex_Selector::ANCESTOR_OF)
|
853
|
-
{ return false; }
|
854
|
-
const Complex_Selector* r_innermost = rhs->last();
|
855
|
-
if (r_innermost->combinator() != Complex_Selector::ANCESTOR_OF)
|
856
|
-
{ return false; }
|
857
|
-
// more complex (i.e., longer) selectors are always more specific
|
858
|
-
size_t l_len = lhs->length(), r_len = rhs->length();
|
859
|
-
if (l_len > r_len)
|
860
|
-
{ return false; }
|
861
|
-
|
862
|
-
if (l_len == 1)
|
863
|
-
{ return lhs->head()->is_superselector_of(rhs->last()->head(), wrapping); }
|
864
|
-
|
865
|
-
// we have to look one tail deeper, since we cary the
|
866
|
-
// combinator around for it (which is important here)
|
867
|
-
if (rhs->tail() && lhs->tail() && combinator() != Complex_Selector::ANCESTOR_OF) {
|
868
|
-
Complex_Selector_Obj lhs_tail = lhs->tail();
|
869
|
-
Complex_Selector_Obj rhs_tail = rhs->tail();
|
870
|
-
if (lhs_tail->combinator() != rhs_tail->combinator()) return false;
|
871
|
-
if (lhs_tail->head() && !rhs_tail->head()) return false;
|
872
|
-
if (!lhs_tail->head() && rhs_tail->head()) return false;
|
873
|
-
if (lhs_tail->head() && rhs_tail->head()) {
|
874
|
-
if (!lhs_tail->head()->is_superselector_of(rhs_tail->head())) return false;
|
875
|
-
}
|
876
|
-
}
|
631
|
+
statement_type(MEDIA);
|
632
|
+
}
|
877
633
|
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
marker = marker->tail();
|
886
|
-
}
|
887
|
-
if (!found)
|
888
|
-
{ return false; }
|
889
|
-
|
890
|
-
/*
|
891
|
-
Hmm, I hope I have the logic right:
|
892
|
-
|
893
|
-
if lhs has a combinator:
|
894
|
-
if !(marker has a combinator) return false
|
895
|
-
if !(lhs.combinator == '~' ? marker.combinator != '>' : lhs.combinator == marker.combinator) return false
|
896
|
-
return lhs.tail-without-innermost.is_superselector_of(marker.tail-without-innermost)
|
897
|
-
else if marker has a combinator:
|
898
|
-
if !(marker.combinator == ">") return false
|
899
|
-
return lhs.tail.is_superselector_of(marker.tail)
|
900
|
-
else
|
901
|
-
return lhs.tail.is_superselector_of(marker.tail)
|
902
|
-
*/
|
903
|
-
if (lhs->combinator() != Complex_Selector::ANCESTOR_OF)
|
904
|
-
{
|
905
|
-
if (marker->combinator() == Complex_Selector::ANCESTOR_OF)
|
906
|
-
{ return false; }
|
907
|
-
if (!(lhs->combinator() == Complex_Selector::PRECEDES ? marker->combinator() != Complex_Selector::PARENT_OF : lhs->combinator() == marker->combinator()))
|
908
|
-
{ return false; }
|
909
|
-
return lhs->tail()->is_superselector_of(marker->tail());
|
910
|
-
}
|
911
|
-
else if (marker->combinator() != Complex_Selector::ANCESTOR_OF)
|
912
|
-
{
|
913
|
-
if (marker->combinator() != Complex_Selector::PARENT_OF)
|
914
|
-
{ return false; }
|
915
|
-
return lhs->tail()->is_superselector_of(marker->tail());
|
916
|
-
}
|
917
|
-
return lhs->tail()->is_superselector_of(marker->tail());
|
918
|
-
}
|
919
|
-
|
920
|
-
size_t Complex_Selector::length() const
|
921
|
-
{
|
922
|
-
// TODO: make this iterative
|
923
|
-
if (!tail()) return 1;
|
924
|
-
return 1 + tail()->length();
|
925
|
-
}
|
926
|
-
|
927
|
-
// append another complex selector at the end
|
928
|
-
// check if we need to append some headers
|
929
|
-
// then we need to check for the combinator
|
930
|
-
// only then we can safely set the new tail
|
931
|
-
void Complex_Selector::append(Complex_Selector_Obj ss, Backtraces& traces)
|
932
|
-
{
|
933
|
-
|
934
|
-
Complex_Selector_Obj t = ss->tail();
|
935
|
-
Combinator c = ss->combinator();
|
936
|
-
String_Obj r = ss->reference();
|
937
|
-
Compound_Selector_Obj h = ss->head();
|
938
|
-
|
939
|
-
if (ss->has_line_feed()) has_line_feed(true);
|
940
|
-
if (ss->has_line_break()) has_line_break(true);
|
941
|
-
|
942
|
-
// append old headers
|
943
|
-
if (h && h->length()) {
|
944
|
-
if (last()->combinator() != ANCESTOR_OF && c != ANCESTOR_OF) {
|
945
|
-
traces.push_back(Backtrace(pstate()));
|
946
|
-
throw Exception::InvalidParent(this, traces, ss);
|
947
|
-
} else if (last()->head_ && last()->head_->length()) {
|
948
|
-
Compound_Selector_Obj rh = last()->head();
|
949
|
-
size_t i;
|
950
|
-
size_t L = h->length();
|
951
|
-
if (Cast<Type_Selector>(h->first())) {
|
952
|
-
if (Class_Selector* cs = Cast<Class_Selector>(rh->last())) {
|
953
|
-
Class_Selector* sqs = SASS_MEMORY_COPY(cs);
|
954
|
-
sqs->name(sqs->name() + (*h)[0]->name());
|
955
|
-
sqs->pstate((*h)[0]->pstate());
|
956
|
-
(*rh)[rh->length()-1] = sqs;
|
957
|
-
rh->pstate(h->pstate());
|
958
|
-
for (i = 1; i < L; ++i) rh->append((*h)[i]);
|
959
|
-
} else if (Id_Selector* is = Cast<Id_Selector>(rh->last())) {
|
960
|
-
Id_Selector* sqs = SASS_MEMORY_COPY(is);
|
961
|
-
sqs->name(sqs->name() + (*h)[0]->name());
|
962
|
-
sqs->pstate((*h)[0]->pstate());
|
963
|
-
(*rh)[rh->length()-1] = sqs;
|
964
|
-
rh->pstate(h->pstate());
|
965
|
-
for (i = 1; i < L; ++i) rh->append((*h)[i]);
|
966
|
-
} else if (Type_Selector* ts = Cast<Type_Selector>(rh->last())) {
|
967
|
-
Type_Selector* tss = SASS_MEMORY_COPY(ts);
|
968
|
-
tss->name(tss->name() + (*h)[0]->name());
|
969
|
-
tss->pstate((*h)[0]->pstate());
|
970
|
-
(*rh)[rh->length()-1] = tss;
|
971
|
-
rh->pstate(h->pstate());
|
972
|
-
for (i = 1; i < L; ++i) rh->append((*h)[i]);
|
973
|
-
} else if (Placeholder_Selector* ps = Cast<Placeholder_Selector>(rh->last())) {
|
974
|
-
Placeholder_Selector* pss = SASS_MEMORY_COPY(ps);
|
975
|
-
pss->name(pss->name() + (*h)[0]->name());
|
976
|
-
pss->pstate((*h)[0]->pstate());
|
977
|
-
(*rh)[rh->length()-1] = pss;
|
978
|
-
rh->pstate(h->pstate());
|
979
|
-
for (i = 1; i < L; ++i) rh->append((*h)[i]);
|
980
|
-
} else {
|
981
|
-
last()->head_->concat(h);
|
982
|
-
}
|
983
|
-
} else {
|
984
|
-
last()->head_->concat(h);
|
985
|
-
}
|
986
|
-
} else if (last()->head_) {
|
987
|
-
last()->head_->concat(h);
|
988
|
-
}
|
989
|
-
} else {
|
990
|
-
// std::cerr << "has no or empty head\n";
|
991
|
-
}
|
634
|
+
CssMediaQuery::CssMediaQuery(SourceSpan pstate) :
|
635
|
+
AST_Node(pstate),
|
636
|
+
modifier_(""),
|
637
|
+
type_(""),
|
638
|
+
features_()
|
639
|
+
{
|
640
|
+
}
|
992
641
|
|
993
|
-
|
994
|
-
|
995
|
-
if (last->combinator() != ANCESTOR_OF && c != ANCESTOR_OF) {
|
996
|
-
Complex_Selector* inter = SASS_MEMORY_NEW(Complex_Selector, pstate());
|
997
|
-
inter->reference(r);
|
998
|
-
inter->combinator(c);
|
999
|
-
inter->tail(t);
|
1000
|
-
last->tail(inter);
|
1001
|
-
} else {
|
1002
|
-
if (last->combinator() == ANCESTOR_OF) {
|
1003
|
-
last->combinator(c);
|
1004
|
-
last->reference(r);
|
1005
|
-
}
|
1006
|
-
last->tail(t);
|
1007
|
-
}
|
1008
|
-
}
|
642
|
+
/////////////////////////////////////////////////////////////////////////
|
643
|
+
/////////////////////////////////////////////////////////////////////////
|
1009
644
|
|
645
|
+
bool CssMediaQuery::operator==(const CssMediaQuery& rhs) const
|
646
|
+
{
|
647
|
+
return type_ == rhs.type_
|
648
|
+
&& modifier_ == rhs.modifier_
|
649
|
+
&& features_ == rhs.features_;
|
1010
650
|
}
|
1011
651
|
|
1012
|
-
|
652
|
+
// Implemented after dart-sass (maybe move to other class?)
|
653
|
+
CssMediaQuery_Obj CssMediaQuery::merge(CssMediaQuery_Obj& other)
|
1013
654
|
{
|
1014
|
-
Complex_Selector_Obj tail = this->tail();
|
1015
|
-
Compound_Selector_Obj head = this->head();
|
1016
|
-
Selector_List* parents = pstack.back();
|
1017
655
|
|
1018
|
-
|
1019
|
-
|
1020
|
-
retval->append(this);
|
1021
|
-
return retval;
|
1022
|
-
}
|
656
|
+
sass::string ourType = this->type();
|
657
|
+
Util::ascii_str_tolower(&ourType);
|
1023
658
|
|
1024
|
-
|
1025
|
-
|
659
|
+
sass::string theirType = other->type();
|
660
|
+
Util::ascii_str_tolower(&theirType);
|
1026
661
|
|
1027
|
-
|
662
|
+
sass::string ourModifier = this->modifier();
|
663
|
+
Util::ascii_str_tolower(&ourModifier);
|
1028
664
|
|
1029
|
-
|
1030
|
-
|
1031
|
-
// mix parent complex selector into the compound list
|
1032
|
-
if (Cast<Parent_Selector>((*head)[0])) {
|
1033
|
-
retval = SASS_MEMORY_NEW(Selector_List, pstate());
|
665
|
+
sass::string theirModifier = other->modifier();
|
666
|
+
Util::ascii_str_tolower(&theirModifier);
|
1034
667
|
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
int i = pstack.size() - 1;
|
1039
|
-
while (!parents && i > -1) {
|
1040
|
-
parents = pstack.at(i--);
|
1041
|
-
}
|
1042
|
-
}
|
668
|
+
sass::string type;
|
669
|
+
sass::string modifier;
|
670
|
+
sass::vector<sass::string> features;
|
1043
671
|
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
s->pstate(pstate());
|
1070
|
-
// append new tail
|
1071
|
-
s->append(ss, traces);
|
1072
|
-
retval->append(s);
|
1073
|
-
}
|
1074
|
-
}
|
1075
|
-
}
|
1076
|
-
// have no tails but parents
|
1077
|
-
// loop above is inside out
|
1078
|
-
else {
|
1079
|
-
for (size_t i = 0, iL = parents->length(); i < iL; ++i) {
|
1080
|
-
Complex_Selector_Obj parent = (*parents)[i];
|
1081
|
-
Complex_Selector_Obj s = SASS_MEMORY_CLONE(parent);
|
1082
|
-
Complex_Selector_Obj ss = SASS_MEMORY_CLONE(this);
|
1083
|
-
// this is only if valid if the parent has no trailing op
|
1084
|
-
// otherwise we cannot append more simple selectors to head
|
1085
|
-
if (parent->last()->combinator() != ANCESTOR_OF) {
|
1086
|
-
traces.push_back(Backtrace(pstate()));
|
1087
|
-
throw Exception::InvalidParent(parent, traces, ss);
|
1088
|
-
}
|
1089
|
-
ss->tail(tail ? SASS_MEMORY_CLONE(tail) : NULL);
|
1090
|
-
Compound_Selector_Obj h = SASS_MEMORY_COPY(head_);
|
1091
|
-
// remove parent selector from sequence
|
1092
|
-
if (h->length()) {
|
1093
|
-
h->erase(h->begin());
|
1094
|
-
ss->head(h);
|
1095
|
-
} else {
|
1096
|
-
ss->head({});
|
1097
|
-
}
|
1098
|
-
// \/ IMO ruby sass bug \/
|
1099
|
-
ss->has_line_feed(false);
|
1100
|
-
// adjust for parent selector (1 char)
|
1101
|
-
// if (h->length()) {
|
1102
|
-
// ParserState state(h->at(0)->pstate());
|
1103
|
-
// state.offset.column += 1;
|
1104
|
-
// state.column -= 1;
|
1105
|
-
// (*h)[0]->pstate(state);
|
1106
|
-
// }
|
1107
|
-
// keep old parser state
|
1108
|
-
s->pstate(pstate());
|
1109
|
-
// append new tail
|
1110
|
-
s->append(ss, traces);
|
1111
|
-
retval->append(s);
|
1112
|
-
}
|
1113
|
-
}
|
672
|
+
if (ourType.empty() && theirType.empty()) {
|
673
|
+
CssMediaQuery_Obj query = SASS_MEMORY_NEW(CssMediaQuery, pstate());
|
674
|
+
sass::vector<sass::string> f1(this->features());
|
675
|
+
sass::vector<sass::string> f2(other->features());
|
676
|
+
features.insert(features.end(), f1.begin(), f1.end());
|
677
|
+
features.insert(features.end(), f2.begin(), f2.end());
|
678
|
+
query->features(features);
|
679
|
+
return query;
|
680
|
+
}
|
681
|
+
|
682
|
+
if ((ourModifier == "not") != (theirModifier == "not")) {
|
683
|
+
if (ourType == theirType) {
|
684
|
+
sass::vector<sass::string> negativeFeatures =
|
685
|
+
ourModifier == "not" ? this->features() : other->features();
|
686
|
+
sass::vector<sass::string> positiveFeatures =
|
687
|
+
ourModifier == "not" ? other->features() : this->features();
|
688
|
+
|
689
|
+
// If the negative features are a subset of the positive features, the
|
690
|
+
// query is empty. For example, `not screen and (color)` has no
|
691
|
+
// intersection with `screen and (color) and (grid)`.
|
692
|
+
// However, `not screen and (color)` *does* intersect with `screen and
|
693
|
+
// (grid)`, because it means `not (screen and (color))` and so it allows
|
694
|
+
// a screen with no color but with a grid.
|
695
|
+
if (listIsSubsetOrEqual(negativeFeatures, positiveFeatures)) {
|
696
|
+
return SASS_MEMORY_NEW(CssMediaQuery, pstate());
|
1114
697
|
}
|
1115
|
-
// have no parent but some tails
|
1116
698
|
else {
|
1117
|
-
|
1118
|
-
for (size_t n = 0, nL = tails->length(); n < nL; ++n) {
|
1119
|
-
Complex_Selector_Obj cpy = SASS_MEMORY_CLONE(this);
|
1120
|
-
cpy->tail(SASS_MEMORY_CLONE(tails->at(n)));
|
1121
|
-
cpy->head(SASS_MEMORY_NEW(Compound_Selector, head->pstate()));
|
1122
|
-
for (size_t i = 1, L = this->head()->length(); i < L; ++i)
|
1123
|
-
cpy->head()->append((*this->head())[i]);
|
1124
|
-
if (!cpy->head()->length()) cpy->head({});
|
1125
|
-
retval->append(cpy->skip_empty_reference());
|
1126
|
-
}
|
1127
|
-
}
|
1128
|
-
// have no parent nor tails
|
1129
|
-
else {
|
1130
|
-
Complex_Selector_Obj cpy = SASS_MEMORY_CLONE(this);
|
1131
|
-
cpy->head(SASS_MEMORY_NEW(Compound_Selector, head->pstate()));
|
1132
|
-
for (size_t i = 1, L = this->head()->length(); i < L; ++i)
|
1133
|
-
cpy->head()->append((*this->head())[i]);
|
1134
|
-
if (!cpy->head()->length()) cpy->head({});
|
1135
|
-
retval->append(cpy->skip_empty_reference());
|
1136
|
-
}
|
699
|
+
return {};
|
1137
700
|
}
|
1138
701
|
}
|
1139
|
-
|
1140
|
-
|
1141
|
-
retval = this->tails(tails);
|
702
|
+
else if (this->matchesAllTypes() || other->matchesAllTypes()) {
|
703
|
+
return {};
|
1142
704
|
}
|
1143
705
|
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
706
|
+
if (ourModifier == "not") {
|
707
|
+
modifier = theirModifier;
|
708
|
+
type = theirType;
|
709
|
+
features = other->features();
|
710
|
+
}
|
711
|
+
else {
|
712
|
+
modifier = ourModifier;
|
713
|
+
type = ourType;
|
714
|
+
features = this->features();
|
1150
715
|
}
|
1151
|
-
|
1152
|
-
return retval.detach();
|
1153
|
-
|
1154
716
|
}
|
1155
|
-
|
1156
|
-
|
1157
|
-
|
1158
|
-
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
1166
|
-
|
717
|
+
else if (ourModifier == "not") {
|
718
|
+
SASS_ASSERT(theirModifier == "not", "modifiers not is sync");
|
719
|
+
|
720
|
+
// CSS has no way of representing "neither screen nor print".
|
721
|
+
if (ourType != theirType) return {};
|
722
|
+
|
723
|
+
auto moreFeatures = this->features().size() > other->features().size()
|
724
|
+
? this->features()
|
725
|
+
: other->features();
|
726
|
+
auto fewerFeatures = this->features().size() > other->features().size()
|
727
|
+
? other->features()
|
728
|
+
: this->features();
|
729
|
+
|
730
|
+
// If one set of features is a superset of the other,
|
731
|
+
// use those features because they're strictly narrower.
|
732
|
+
if (listIsSubsetOrEqual(fewerFeatures, moreFeatures)) {
|
733
|
+
modifier = ourModifier; // "not"
|
734
|
+
type = ourType;
|
735
|
+
features = moreFeatures;
|
1167
736
|
}
|
737
|
+
else {
|
738
|
+
// Otherwise, there's no way to
|
739
|
+
// represent the intersection.
|
740
|
+
return {};
|
741
|
+
}
|
742
|
+
|
1168
743
|
}
|
1169
744
|
else {
|
1170
|
-
|
1171
|
-
|
1172
|
-
|
1173
|
-
|
1174
|
-
|
1175
|
-
|
1176
|
-
|
1177
|
-
|
1178
|
-
|
1179
|
-
|
1180
|
-
|
1181
|
-
|
1182
|
-
|
1183
|
-
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
745
|
+
if (this->matchesAllTypes()) {
|
746
|
+
modifier = theirModifier;
|
747
|
+
// Omit the type if either input query did, since that indicates that they
|
748
|
+
// aren't targeting a browser that requires "all and".
|
749
|
+
type = (other->matchesAllTypes() && ourType.empty()) ? "" : theirType;
|
750
|
+
sass::vector<sass::string> f1(this->features());
|
751
|
+
sass::vector<sass::string> f2(other->features());
|
752
|
+
features.insert(features.end(), f1.begin(), f1.end());
|
753
|
+
features.insert(features.end(), f2.begin(), f2.end());
|
754
|
+
}
|
755
|
+
else if (other->matchesAllTypes()) {
|
756
|
+
modifier = ourModifier;
|
757
|
+
type = ourType;
|
758
|
+
sass::vector<sass::string> f1(this->features());
|
759
|
+
sass::vector<sass::string> f2(other->features());
|
760
|
+
features.insert(features.end(), f1.begin(), f1.end());
|
761
|
+
features.insert(features.end(), f2.begin(), f2.end());
|
762
|
+
}
|
763
|
+
else if (ourType != theirType) {
|
764
|
+
return SASS_MEMORY_NEW(CssMediaQuery, pstate());
|
765
|
+
}
|
766
|
+
else {
|
767
|
+
modifier = ourModifier.empty() ? theirModifier : ourModifier;
|
768
|
+
type = ourType;
|
769
|
+
sass::vector<sass::string> f1(this->features());
|
770
|
+
sass::vector<sass::string> f2(other->features());
|
771
|
+
features.insert(features.end(), f1.begin(), f1.end());
|
772
|
+
features.insert(features.end(), f2.begin(), f2.end());
|
1189
773
|
}
|
1190
|
-
// advance to next
|
1191
|
-
cur = cur->tail_;
|
1192
774
|
}
|
1193
|
-
|
1194
|
-
|
775
|
+
|
776
|
+
CssMediaQuery_Obj query = SASS_MEMORY_NEW(CssMediaQuery, pstate());
|
777
|
+
query->modifier(modifier == ourModifier ? this->modifier() : other->modifier());
|
778
|
+
query->type(ourType.empty() ? other->type() : this->type());
|
779
|
+
query->features(features);
|
780
|
+
return query;
|
1195
781
|
}
|
1196
782
|
|
1197
|
-
|
783
|
+
CssMediaQuery::CssMediaQuery(const CssMediaQuery* ptr) :
|
784
|
+
AST_Node(*ptr),
|
785
|
+
modifier_(ptr->modifier_),
|
786
|
+
type_(ptr->type_),
|
787
|
+
features_(ptr->features_)
|
1198
788
|
{
|
1199
|
-
return const_cast<Complex_Selector*>(first());
|
1200
789
|
}
|
1201
790
|
|
1202
|
-
|
1203
|
-
|
791
|
+
/////////////////////////////////////////////////////////////////////////
|
792
|
+
// ToDo: finalize specificity implementation
|
793
|
+
/////////////////////////////////////////////////////////////////////////
|
794
|
+
|
795
|
+
size_t SelectorList::maxSpecificity() const
|
1204
796
|
{
|
1205
|
-
|
1206
|
-
|
1207
|
-
|
1208
|
-
while (nxt) {
|
1209
|
-
cur = nxt;
|
1210
|
-
nxt = cur->tail_.ptr();
|
797
|
+
size_t specificity = 0;
|
798
|
+
for (auto complex : elements()) {
|
799
|
+
specificity = std::max(specificity, complex->maxSpecificity());
|
1211
800
|
}
|
1212
|
-
return
|
801
|
+
return specificity;
|
1213
802
|
}
|
1214
803
|
|
1215
|
-
|
804
|
+
size_t SelectorList::minSpecificity() const
|
1216
805
|
{
|
1217
|
-
|
806
|
+
size_t specificity = 0;
|
807
|
+
for (auto complex : elements()) {
|
808
|
+
specificity = std::min(specificity, complex->minSpecificity());
|
809
|
+
}
|
810
|
+
return specificity;
|
1218
811
|
}
|
1219
812
|
|
1220
|
-
|
813
|
+
size_t CompoundSelector::maxSpecificity() const
|
1221
814
|
{
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1225
|
-
|
1226
|
-
|
1227
|
-
return c;
|
815
|
+
size_t specificity = 0;
|
816
|
+
for (auto simple : elements()) {
|
817
|
+
specificity += simple->maxSpecificity();
|
818
|
+
}
|
819
|
+
return specificity;
|
1228
820
|
}
|
1229
821
|
|
1230
|
-
|
822
|
+
size_t CompoundSelector::minSpecificity() const
|
1231
823
|
{
|
1232
|
-
|
1233
|
-
|
1234
|
-
|
1235
|
-
|
824
|
+
size_t specificity = 0;
|
825
|
+
for (auto simple : elements()) {
|
826
|
+
specificity += simple->minSpecificity();
|
827
|
+
}
|
828
|
+
return specificity;
|
1236
829
|
}
|
1237
830
|
|
1238
|
-
|
831
|
+
size_t ComplexSelector::maxSpecificity() const
|
1239
832
|
{
|
1240
|
-
|
1241
|
-
|
833
|
+
size_t specificity = 0;
|
834
|
+
for (auto component : elements()) {
|
835
|
+
specificity += component->maxSpecificity();
|
836
|
+
}
|
837
|
+
return specificity;
|
1242
838
|
}
|
1243
839
|
|
1244
|
-
|
1245
|
-
// list is a superselector of the given left side selector
|
1246
|
-
bool Complex_Selector::is_superselector_of(const Selector_List* sub, std::string wrapping) const
|
840
|
+
size_t ComplexSelector::minSpecificity() const
|
1247
841
|
{
|
1248
|
-
|
1249
|
-
for(
|
1250
|
-
|
842
|
+
size_t specificity = 0;
|
843
|
+
for (auto component : elements()) {
|
844
|
+
specificity += component->minSpecificity();
|
1251
845
|
}
|
1252
|
-
return
|
846
|
+
return specificity;
|
1253
847
|
}
|
1254
848
|
|
1255
849
|
/////////////////////////////////////////////////////////////////////////
|
850
|
+
// ToDo: this might be done easier with new selector format
|
1256
851
|
/////////////////////////////////////////////////////////////////////////
|
1257
852
|
|
1258
|
-
|
1259
|
-
|
1260
|
-
Vectorized<Complex_Selector_Obj>(s),
|
1261
|
-
schema_({}),
|
1262
|
-
wspace_(0)
|
1263
|
-
{ }
|
1264
|
-
Selector_List::Selector_List(const Selector_List* ptr)
|
1265
|
-
: Selector(ptr),
|
1266
|
-
Vectorized<Complex_Selector_Obj>(*ptr),
|
1267
|
-
schema_(ptr->schema_),
|
1268
|
-
wspace_(ptr->wspace_)
|
1269
|
-
{ }
|
1270
|
-
|
1271
|
-
bool Selector_List::find ( bool (*f)(AST_Node_Obj) )
|
853
|
+
sass::vector<ComplexSelectorObj>
|
854
|
+
CompoundSelector::resolve_parent_refs(SelectorStack pstack, Backtraces& traces, bool implicit_parent)
|
1272
855
|
{
|
1273
|
-
// check children first
|
1274
|
-
for (Complex_Selector_Obj sel : elements()) {
|
1275
|
-
if (sel->find(f)) return true;
|
1276
|
-
}
|
1277
|
-
// execute last
|
1278
|
-
return f(this);
|
1279
|
-
}
|
1280
856
|
|
1281
|
-
|
1282
|
-
|
1283
|
-
Selector_List_Obj list = schema() ?
|
1284
|
-
eval(schema()) : eval(this);
|
1285
|
-
list->schema(schema());
|
1286
|
-
return list;
|
1287
|
-
}
|
857
|
+
auto parent = pstack.back();
|
858
|
+
sass::vector<ComplexSelectorObj> rv;
|
1288
859
|
|
1289
|
-
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1295
|
-
|
860
|
+
for (SimpleSelectorObj simple : elements()) {
|
861
|
+
if (PseudoSelector * pseudo = Cast<PseudoSelector>(simple)) {
|
862
|
+
if (SelectorList* sel = Cast<SelectorList>(pseudo->selector())) {
|
863
|
+
if (parent) {
|
864
|
+
pseudo->selector(sel->resolve_parent_refs(
|
865
|
+
pstack, traces, implicit_parent));
|
866
|
+
}
|
867
|
+
}
|
868
|
+
}
|
1296
869
|
}
|
1297
|
-
return ss;
|
1298
|
-
}
|
1299
870
|
|
1300
|
-
|
1301
|
-
|
1302
|
-
for (size_t i = 0, l = length(); i < l; i++) {
|
1303
|
-
at(i) = SASS_MEMORY_CLONE(at(i));
|
1304
|
-
}
|
1305
|
-
}
|
871
|
+
// Mix with parents from stack
|
872
|
+
if (hasRealParent()) {
|
1306
873
|
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1318
|
-
if
|
1319
|
-
|
874
|
+
if (parent.isNull()) {
|
875
|
+
return { wrapInComplex() };
|
876
|
+
}
|
877
|
+
else {
|
878
|
+
for (auto complex : parent->elements()) {
|
879
|
+
// The parent complex selector has a compound selector
|
880
|
+
if (CompoundSelectorObj tail = Cast<CompoundSelector>(complex->last())) {
|
881
|
+
// Create a copy to alter it
|
882
|
+
complex = SASS_MEMORY_COPY(complex);
|
883
|
+
tail = SASS_MEMORY_COPY(tail);
|
884
|
+
|
885
|
+
// Check if we can merge front with back
|
886
|
+
if (length() > 0 && tail->length() > 0) {
|
887
|
+
SimpleSelectorObj back = tail->last();
|
888
|
+
SimpleSelectorObj front = first();
|
889
|
+
auto simple_back = Cast<SimpleSelector>(back);
|
890
|
+
auto simple_front = Cast<TypeSelector>(front);
|
891
|
+
if (simple_front && simple_back) {
|
892
|
+
simple_back = SASS_MEMORY_COPY(simple_back);
|
893
|
+
auto name = simple_back->name();
|
894
|
+
name += simple_front->name();
|
895
|
+
simple_back->name(name);
|
896
|
+
tail->elements().back() = simple_back;
|
897
|
+
tail->elements().insert(tail->end(),
|
898
|
+
begin() + 1, end());
|
899
|
+
}
|
900
|
+
else {
|
901
|
+
tail->concat(this);
|
902
|
+
}
|
903
|
+
}
|
904
|
+
else {
|
905
|
+
tail->concat(this);
|
1320
906
|
}
|
1321
|
-
|
907
|
+
|
908
|
+
complex->elements().back() = tail;
|
909
|
+
// Append to results
|
910
|
+
rv.push_back(complex);
|
911
|
+
}
|
912
|
+
else {
|
913
|
+
// Can't insert parent that ends with a combinator
|
914
|
+
// where the parent selector is followed by something
|
915
|
+
if (parent && length() > 0) {
|
916
|
+
throw Exception::InvalidParent(parent, traces, this);
|
917
|
+
}
|
918
|
+
// Create a copy to alter it
|
919
|
+
complex = SASS_MEMORY_COPY(complex);
|
920
|
+
// Just append ourself
|
921
|
+
complex->append(this);
|
922
|
+
// Append to results
|
923
|
+
rv.push_back(complex);
|
1322
924
|
}
|
1323
|
-
}
|
1324
|
-
// otherwise remove the first item from head
|
1325
|
-
else {
|
1326
|
-
(*this)[i]->head()->erase((*this)[i]->head()->begin());
|
1327
925
|
}
|
1328
926
|
}
|
1329
927
|
}
|
1330
|
-
}
|
1331
928
|
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
bool Selector_List::has_real_parent_ref() const
|
1341
|
-
{
|
1342
|
-
for (Complex_Selector_Obj s : elements()) {
|
1343
|
-
if (s && s->has_real_parent_ref()) return true;
|
929
|
+
// No parents
|
930
|
+
else {
|
931
|
+
// Create a new wrapper to wrap ourself
|
932
|
+
auto complex = SASS_MEMORY_NEW(ComplexSelector, pstate());
|
933
|
+
// Just append ourself
|
934
|
+
complex->append(this);
|
935
|
+
// Append to results
|
936
|
+
rv.push_back(complex);
|
1344
937
|
}
|
1345
|
-
return false;
|
1346
|
-
}
|
1347
938
|
|
1348
|
-
|
1349
|
-
{
|
1350
|
-
// if (c->has_reference()) has_reference(true);
|
1351
|
-
}
|
939
|
+
return rv;
|
1352
940
|
|
1353
|
-
// it's a superselector if every selector of the right side
|
1354
|
-
// list is a superselector of the given left side selector
|
1355
|
-
bool Selector_List::is_superselector_of(const Selector_List* sub, std::string wrapping) const
|
1356
|
-
{
|
1357
|
-
// Check every rhs selector against left hand list
|
1358
|
-
for(size_t i = 0, L = sub->length(); i < L; ++i) {
|
1359
|
-
if (!is_superselector_of((*sub)[i], wrapping)) return false;
|
1360
|
-
}
|
1361
|
-
return true;
|
1362
941
|
}
|
1363
942
|
|
1364
|
-
|
1365
|
-
// is a superselector of any one of the left side selectors
|
1366
|
-
bool Selector_List::is_superselector_of(const Compound_Selector* sub, std::string wrapping) const
|
943
|
+
bool cmpSimpleSelectors(SimpleSelector* a, SimpleSelector* b)
|
1367
944
|
{
|
1368
|
-
|
1369
|
-
for(size_t i = 0, L = length(); i < L; ++i) {
|
1370
|
-
if ((*this)[i]->is_superselector_of(sub, wrapping)) return true;
|
1371
|
-
}
|
1372
|
-
return false;
|
945
|
+
return (a->getSortOrder() < b->getSortOrder());
|
1373
946
|
}
|
1374
947
|
|
1375
|
-
|
1376
|
-
// is a superselector of any one of the left side selectors
|
1377
|
-
bool Selector_List::is_superselector_of(const Complex_Selector* sub, std::string wrapping) const
|
948
|
+
void CompoundSelector::sortChildren()
|
1378
949
|
{
|
1379
|
-
|
1380
|
-
for(size_t i = 0, L = length(); i < L; ++i) {
|
1381
|
-
if ((*this)[i]->is_superselector_of(sub)) return true;
|
1382
|
-
}
|
1383
|
-
return false;
|
950
|
+
std::sort(begin(), end(), cmpSimpleSelectors);
|
1384
951
|
}
|
1385
952
|
|
1386
|
-
|
953
|
+
/* better return sass::vector? only - is empty container anyway? */
|
954
|
+
SelectorList* ComplexSelector::resolve_parent_refs(SelectorStack pstack, Backtraces& traces, bool implicit_parent)
|
1387
955
|
{
|
1388
956
|
|
1389
|
-
|
1390
|
-
for (auto complex_sel : extendee->elements()) {
|
1391
|
-
Complex_Selector_Obj c = complex_sel;
|
957
|
+
sass::vector<sass::vector<ComplexSelectorObj>> vars;
|
1392
958
|
|
959
|
+
auto parent = pstack.back();
|
1393
960
|
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1397
|
-
while (pIter) {
|
1398
|
-
Compound_Selector_Obj pHead = pIter->head();
|
1399
|
-
if (pHead && Cast<Parent_Selector>(pHead->elements()[0]) == NULL) {
|
1400
|
-
compound_sel = pHead;
|
1401
|
-
break;
|
1402
|
-
}
|
961
|
+
if (has_real_parent_ref() && !parent) {
|
962
|
+
throw Exception::TopLevelParent(traces, pstate());
|
963
|
+
}
|
1403
964
|
|
1404
|
-
|
1405
|
-
}
|
965
|
+
if (!chroots() && parent) {
|
1406
966
|
|
1407
|
-
if (!
|
1408
|
-
|
967
|
+
if (!has_real_parent_ref() && !implicit_parent) {
|
968
|
+
SelectorList* retval = SASS_MEMORY_NEW(SelectorList, pstate(), 1);
|
969
|
+
retval->append(this);
|
970
|
+
return retval;
|
1409
971
|
}
|
1410
972
|
|
1411
|
-
|
973
|
+
vars.push_back(parent->elements());
|
974
|
+
}
|
1412
975
|
|
1413
|
-
|
1414
|
-
|
976
|
+
for (auto sel : elements()) {
|
977
|
+
if (CompoundSelectorObj comp = Cast<CompoundSelector>(sel)) {
|
978
|
+
auto asd = comp->resolve_parent_refs(pstack, traces, implicit_parent);
|
979
|
+
if (asd.size() > 0) vars.push_back(asd);
|
980
|
+
}
|
981
|
+
else {
|
982
|
+
// ToDo: merge together sequences whenever possible
|
983
|
+
auto cont = SASS_MEMORY_NEW(ComplexSelector, pstate());
|
984
|
+
cont->append(sel);
|
985
|
+
vars.push_back({ cont });
|
1415
986
|
}
|
1416
987
|
}
|
1417
|
-
};
|
1418
988
|
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
989
|
+
// Need complex selectors to preserve linefeeds
|
990
|
+
sass::vector<sass::vector<ComplexSelectorObj>> res = permutateAlt(vars);
|
991
|
+
|
992
|
+
// std::reverse(std::begin(res), std::end(res));
|
993
|
+
|
994
|
+
auto lst = SASS_MEMORY_NEW(SelectorList, pstate());
|
995
|
+
for (auto items : res) {
|
996
|
+
if (items.size() > 0) {
|
997
|
+
ComplexSelectorObj first = SASS_MEMORY_COPY(items[0]);
|
998
|
+
first->hasPreLineFeed(first->hasPreLineFeed() || (!has_real_parent_ref() && hasPreLineFeed()));
|
999
|
+
// ToDo: remove once we know how to handle line feeds
|
1000
|
+
// ToDo: currently a mashup between ruby and dart sass
|
1001
|
+
// if (has_real_parent_ref()) first->has_line_feed(false);
|
1002
|
+
// first->has_line_break(first->has_line_break() || has_line_break());
|
1003
|
+
first->chroots(true); // has been resolved by now
|
1004
|
+
for (size_t i = 1; i < items.size(); i += 1) {
|
1005
|
+
first->concat(items[i]);
|
1006
|
+
}
|
1007
|
+
lst->append(first);
|
1426
1008
|
}
|
1427
1009
|
}
|
1428
|
-
return Selector::hash_;
|
1429
|
-
}
|
1430
1010
|
|
1431
|
-
|
1432
|
-
{
|
1433
|
-
unsigned long sum = 0;
|
1434
|
-
unsigned long specificity;
|
1435
|
-
for (size_t i = 0, L = length(); i < L; ++i)
|
1436
|
-
{
|
1437
|
-
specificity = (*this)[i]->specificity();
|
1438
|
-
if (sum < specificity) sum = specificity;
|
1439
|
-
}
|
1440
|
-
return sum;
|
1441
|
-
}
|
1011
|
+
return lst;
|
1442
1012
|
|
1443
|
-
void Selector_List::set_media_block(Media_Block* mb)
|
1444
|
-
{
|
1445
|
-
media_block(mb);
|
1446
|
-
for (Complex_Selector_Obj cs : elements()) {
|
1447
|
-
cs->set_media_block(mb);
|
1448
|
-
}
|
1449
1013
|
}
|
1450
1014
|
|
1451
|
-
|
1015
|
+
SelectorList* SelectorList::resolve_parent_refs(SelectorStack pstack, Backtraces& traces, bool implicit_parent)
|
1452
1016
|
{
|
1453
|
-
|
1454
|
-
|
1017
|
+
SelectorList* rv = SASS_MEMORY_NEW(SelectorList, pstate());
|
1018
|
+
for (auto sel : elements()) {
|
1019
|
+
// Note: this one is tricky as we get back a pointer from resolve parents ...
|
1020
|
+
SelectorListObj res = sel->resolve_parent_refs(pstack, traces, implicit_parent);
|
1021
|
+
// Note: ... and concat will only append the items in elements
|
1022
|
+
// Therefore by passing it directly, the container will leak!
|
1023
|
+
rv->concat(res);
|
1455
1024
|
}
|
1456
|
-
return
|
1025
|
+
return rv;
|
1457
1026
|
}
|
1458
1027
|
|
1459
1028
|
/////////////////////////////////////////////////////////////////////////
|
1460
1029
|
/////////////////////////////////////////////////////////////////////////
|
1461
1030
|
|
1462
1031
|
IMPLEMENT_AST_OPERATORS(Selector_Schema);
|
1463
|
-
IMPLEMENT_AST_OPERATORS(
|
1464
|
-
IMPLEMENT_AST_OPERATORS(
|
1465
|
-
IMPLEMENT_AST_OPERATORS(
|
1466
|
-
IMPLEMENT_AST_OPERATORS(
|
1467
|
-
IMPLEMENT_AST_OPERATORS(
|
1468
|
-
IMPLEMENT_AST_OPERATORS(
|
1469
|
-
IMPLEMENT_AST_OPERATORS(
|
1470
|
-
IMPLEMENT_AST_OPERATORS(
|
1471
|
-
IMPLEMENT_AST_OPERATORS(
|
1472
|
-
IMPLEMENT_AST_OPERATORS(
|
1473
|
-
IMPLEMENT_AST_OPERATORS(Selector_List);
|
1032
|
+
IMPLEMENT_AST_OPERATORS(PlaceholderSelector);
|
1033
|
+
IMPLEMENT_AST_OPERATORS(AttributeSelector);
|
1034
|
+
IMPLEMENT_AST_OPERATORS(TypeSelector);
|
1035
|
+
IMPLEMENT_AST_OPERATORS(ClassSelector);
|
1036
|
+
IMPLEMENT_AST_OPERATORS(IDSelector);
|
1037
|
+
IMPLEMENT_AST_OPERATORS(PseudoSelector);
|
1038
|
+
IMPLEMENT_AST_OPERATORS(SelectorCombinator);
|
1039
|
+
IMPLEMENT_AST_OPERATORS(CompoundSelector);
|
1040
|
+
IMPLEMENT_AST_OPERATORS(ComplexSelector);
|
1041
|
+
IMPLEMENT_AST_OPERATORS(SelectorList);
|
1474
1042
|
|
1475
1043
|
}
|