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