sassc 2.2.1 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/CHANGELOG.md +13 -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 +1 -0
- data/ext/libsass/src/ast.cpp +49 -59
- data/ext/libsass/src/ast.hpp +263 -102
- data/ext/libsass/src/ast_def_macros.hpp +8 -0
- data/ext/libsass/src/ast_fwd_decl.cpp +2 -1
- data/ext/libsass/src/ast_fwd_decl.hpp +40 -116
- data/ext/libsass/src/ast_helpers.hpp +292 -0
- data/ext/libsass/src/ast_sel_cmp.cpp +209 -722
- 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 +559 -1001
- data/ext/libsass/src/ast_selectors.hpp +311 -367
- data/ext/libsass/src/ast_supports.cpp +1 -17
- data/ext/libsass/src/ast_values.cpp +216 -29
- data/ext/libsass/src/ast_values.hpp +42 -33
- data/ext/libsass/src/bind.cpp +1 -1
- data/ext/libsass/src/cencode.c +4 -6
- data/ext/libsass/src/check_nesting.cpp +5 -6
- data/ext/libsass/src/check_nesting.hpp +4 -0
- data/ext/libsass/src/color_maps.cpp +11 -10
- data/ext/libsass/src/color_maps.hpp +0 -8
- data/ext/libsass/src/constants.cpp +5 -0
- data/ext/libsass/src/constants.hpp +6 -0
- data/ext/libsass/src/context.cpp +30 -60
- data/ext/libsass/src/context.hpp +8 -20
- data/ext/libsass/src/cssize.cpp +36 -120
- data/ext/libsass/src/cssize.hpp +4 -10
- data/ext/libsass/src/dart_helpers.hpp +199 -0
- data/ext/libsass/src/debugger.hpp +364 -207
- data/ext/libsass/src/emitter.cpp +3 -4
- data/ext/libsass/src/emitter.hpp +0 -2
- data/ext/libsass/src/environment.hpp +5 -0
- data/ext/libsass/src/error_handling.cpp +21 -0
- data/ext/libsass/src/error_handling.hpp +25 -3
- data/ext/libsass/src/eval.cpp +33 -153
- data/ext/libsass/src/eval.hpp +11 -13
- data/ext/libsass/src/eval_selectors.cpp +75 -0
- data/ext/libsass/src/expand.cpp +214 -167
- data/ext/libsass/src/expand.hpp +26 -6
- data/ext/libsass/src/extender.cpp +1186 -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 +15 -14
- data/ext/libsass/src/file.hpp +5 -12
- data/ext/libsass/src/fn_colors.cpp +12 -10
- data/ext/libsass/src/fn_lists.cpp +12 -11
- data/ext/libsass/src/fn_miscs.cpp +22 -34
- data/ext/libsass/src/fn_numbers.cpp +13 -6
- data/ext/libsass/src/fn_selectors.cpp +94 -124
- data/ext/libsass/src/fn_strings.cpp +16 -14
- data/ext/libsass/src/fn_utils.cpp +5 -6
- data/ext/libsass/src/fn_utils.hpp +9 -3
- data/ext/libsass/src/inspect.cpp +154 -117
- data/ext/libsass/src/inspect.hpp +10 -8
- data/ext/libsass/src/lexer.cpp +17 -81
- data/ext/libsass/src/lexer.hpp +5 -16
- data/ext/libsass/src/listize.cpp +22 -36
- data/ext/libsass/src/listize.hpp +8 -9
- data/ext/libsass/src/memory/SharedPtr.hpp +39 -5
- data/ext/libsass/src/operation.hpp +27 -17
- data/ext/libsass/src/operators.cpp +1 -0
- data/ext/libsass/src/ordered_map.hpp +112 -0
- data/ext/libsass/src/output.cpp +30 -49
- data/ext/libsass/src/output.hpp +1 -1
- data/ext/libsass/src/parser.cpp +211 -381
- data/ext/libsass/src/parser.hpp +17 -15
- data/ext/libsass/src/parser_selectors.cpp +189 -0
- data/ext/libsass/src/permutate.hpp +140 -0
- data/ext/libsass/src/position.hpp +1 -1
- 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.hpp +1 -0
- data/ext/libsass/src/sass2scss.cpp +4 -4
- data/ext/libsass/src/sass_context.cpp +42 -91
- 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 +0 -1
- 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 +5 -3
- data/ext/libsass/src/util.cpp +10 -12
- data/ext/libsass/src/util.hpp +2 -3
- data/ext/libsass/src/util_string.cpp +111 -61
- data/ext/libsass/src/util_string.hpp +61 -8
- data/lib/sassc/engine.rb +5 -3
- data/lib/sassc/functions_handler.rb +8 -8
- data/lib/sassc/native.rb +1 -1
- 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 +1 -1
- metadata +17 -12
- 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
@@ -1,280 +1,275 @@
|
|
1
|
+
// sass.hpp must go before all system headers to get the
|
2
|
+
// __EXTENSIONS__ fix on Solaris.
|
1
3
|
#include "sass.hpp"
|
2
|
-
#include "ast.hpp"
|
3
|
-
#include "context.hpp"
|
4
|
-
#include "node.hpp"
|
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 <set>
|
11
|
-
#include <iomanip>
|
12
|
-
#include <iostream>
|
13
|
-
#include <algorithm>
|
14
|
-
#include <functional>
|
15
|
-
#include <cctype>
|
16
|
-
#include <locale>
|
17
|
-
|
18
|
-
#include "ast_selectors.hpp"
|
19
4
|
|
20
|
-
|
5
|
+
#include "ast.hpp"
|
21
6
|
|
22
7
|
namespace Sass {
|
23
8
|
|
24
|
-
|
9
|
+
// ##########################################################################
|
10
|
+
// Returns the contents of a [SelectorList] that matches only
|
11
|
+
// elements that are matched by both [complex1] and [complex2].
|
12
|
+
// If no such list can be produced, returns `null`.
|
13
|
+
// ##########################################################################
|
14
|
+
// ToDo: fine-tune API to avoid unnecessary wrapper allocations
|
15
|
+
// ##########################################################################
|
16
|
+
std::vector<std::vector<SelectorComponentObj>> unifyComplex(
|
17
|
+
const std::vector<std::vector<SelectorComponentObj>>& complexes)
|
25
18
|
{
|
26
|
-
#ifdef DEBUG_UNIFY
|
27
|
-
const std::string debug_call = "unify(Compound[" + this->to_string() + "], Compound[" + rhs->to_string() + "])";
|
28
|
-
std::cerr << debug_call << std::endl;
|
29
|
-
#endif
|
30
19
|
|
20
|
+
SASS_ASSERT(!complexes.empty(), "Can't unify empty list");
|
21
|
+
if (complexes.size() == 1) return complexes;
|
22
|
+
|
23
|
+
CompoundSelectorObj unifiedBase = SASS_MEMORY_NEW(CompoundSelector, ParserState("[phony]"));
|
24
|
+
for (auto complex : complexes) {
|
25
|
+
SelectorComponentObj base = complex.back();
|
26
|
+
if (CompoundSelector * comp = base->getCompound()) {
|
27
|
+
if (unifiedBase->empty()) {
|
28
|
+
unifiedBase->concat(comp);
|
29
|
+
}
|
30
|
+
else {
|
31
|
+
for (SimpleSelectorObj simple : comp->elements()) {
|
32
|
+
unifiedBase = simple->unifyWith(unifiedBase);
|
33
|
+
if (unifiedBase.isNull()) return {};
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
else {
|
38
|
+
return {};
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
std::vector<std::vector<SelectorComponentObj>> complexesWithoutBases;
|
43
|
+
for (size_t i = 0; i < complexes.size(); i += 1) {
|
44
|
+
std::vector<SelectorComponentObj> sel = complexes[i];
|
45
|
+
sel.pop_back(); // remove last item (base) from the list
|
46
|
+
complexesWithoutBases.push_back(std::move(sel));
|
47
|
+
}
|
48
|
+
|
49
|
+
complexesWithoutBases.back().push_back(unifiedBase);
|
50
|
+
|
51
|
+
return weave(complexesWithoutBases);
|
52
|
+
|
53
|
+
}
|
54
|
+
// EO unifyComplex
|
55
|
+
|
56
|
+
// ##########################################################################
|
57
|
+
// Returns a [CompoundSelector] that matches only elements
|
58
|
+
// that are matched by both [compound1] and [compound2].
|
59
|
+
// If no such selector can be produced, returns `null`.
|
60
|
+
// ##########################################################################
|
61
|
+
CompoundSelector* CompoundSelector::unifyWith(CompoundSelector* rhs)
|
62
|
+
{
|
31
63
|
if (empty()) return rhs;
|
32
|
-
|
33
|
-
for (const
|
34
|
-
unified = sel->
|
64
|
+
CompoundSelectorObj unified = SASS_MEMORY_COPY(rhs);
|
65
|
+
for (const SimpleSelectorObj& sel : elements()) {
|
66
|
+
unified = sel->unifyWith(unified);
|
35
67
|
if (unified.isNull()) break;
|
36
68
|
}
|
37
|
-
|
38
|
-
#ifdef DEBUG_UNIFY
|
39
|
-
std::cerr << "> " << debug_call << " = Compound[" << unified->to_string() << "]" << std::endl;
|
40
|
-
#endif
|
41
69
|
return unified.detach();
|
42
70
|
}
|
43
|
-
|
44
|
-
|
71
|
+
// EO CompoundSelector::unifyWith(CompoundSelector*)
|
72
|
+
|
73
|
+
// ##########################################################################
|
74
|
+
// Returns the compoments of a [CompoundSelector] that matches only elements
|
75
|
+
// matched by both this and [compound]. By default, this just returns a copy
|
76
|
+
// of [compound] with this selector added to the end, or returns the original
|
77
|
+
// array if this selector already exists in it. Returns `null` if unification
|
78
|
+
// is impossible—for example, if there are multiple ID selectors.
|
79
|
+
// ##########################################################################
|
80
|
+
// This is implemented in `selector/simple.dart` as `SimpleSelector::unify`
|
81
|
+
// ##########################################################################
|
82
|
+
CompoundSelector* SimpleSelector::unifyWith(CompoundSelector* rhs)
|
45
83
|
{
|
46
|
-
#ifdef DEBUG_UNIFY
|
47
|
-
const std::string debug_call = "unify(Simple[" + this->to_string() + "], Compound[" + rhs->to_string() + "])";
|
48
|
-
std::cerr << debug_call << std::endl;
|
49
|
-
#endif
|
50
84
|
|
51
85
|
if (rhs->length() == 1) {
|
52
|
-
if (rhs->
|
53
|
-
|
86
|
+
if (rhs->get(0)->is_universal()) {
|
87
|
+
CompoundSelector* this_compound = SASS_MEMORY_NEW(CompoundSelector, pstate());
|
54
88
|
this_compound->append(SASS_MEMORY_COPY(this));
|
55
|
-
|
89
|
+
CompoundSelector* unified = rhs->get(0)->unifyWith(this_compound);
|
56
90
|
if (unified == nullptr || unified != this_compound) delete this_compound;
|
57
|
-
|
58
|
-
#ifdef DEBUG_UNIFY
|
59
|
-
std::cerr << "> " << debug_call << " = " << "Compound[" << unified->to_string() << "]" << std::endl;
|
60
|
-
#endif
|
61
91
|
return unified;
|
62
92
|
}
|
63
93
|
}
|
64
|
-
for (const
|
94
|
+
for (const SimpleSelectorObj& sel : rhs->elements()) {
|
65
95
|
if (*this == *sel) {
|
66
|
-
#ifdef DEBUG_UNIFY
|
67
|
-
std::cerr << "> " << debug_call << " = " << "Compound[" << rhs->to_string() << "]" << std::endl;
|
68
|
-
#endif
|
69
96
|
return rhs;
|
70
97
|
}
|
71
98
|
}
|
72
|
-
const int lhs_order = this->unification_order();
|
73
|
-
size_t i = rhs->length();
|
74
|
-
while (i > 0 && lhs_order < rhs->at(i - 1)->unification_order()) --i;
|
75
|
-
rhs->insert(rhs->begin() + i, this);
|
76
|
-
#ifdef DEBUG_UNIFY
|
77
|
-
std::cerr << "> " << debug_call << " = " << "Compound[" << rhs->to_string() << "]" << std::endl;
|
78
|
-
#endif
|
79
|
-
return rhs;
|
80
|
-
}
|
81
99
|
|
82
|
-
|
83
|
-
{
|
84
|
-
#ifdef DEBUG_UNIFY
|
85
|
-
const std::string debug_call = "unify(Type[" + this->to_string() + "], Simple[" + rhs->to_string() + "])";
|
86
|
-
std::cerr << debug_call << std::endl;
|
87
|
-
#endif
|
100
|
+
CompoundSelectorObj result = SASS_MEMORY_NEW(CompoundSelector, rhs->pstate());
|
88
101
|
|
89
|
-
bool
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
return nullptr;
|
96
|
-
}
|
97
|
-
rhs_ns = true;
|
98
|
-
}
|
99
|
-
bool rhs_name = false;
|
100
|
-
if (!(name_ == rhs->name() || rhs->is_universal())) {
|
101
|
-
if (!(is_universal())) {
|
102
|
-
#ifdef DEBUG_UNIFY
|
103
|
-
std::cerr << "> " << debug_call << " = nullptr" << std::endl;
|
104
|
-
#endif
|
105
|
-
return nullptr;
|
102
|
+
bool addedThis = false;
|
103
|
+
for (auto simple : rhs->elements()) {
|
104
|
+
// Make sure pseudo selectors always come last.
|
105
|
+
if (!addedThis && simple->getPseudoSelector()) {
|
106
|
+
result->append(this);
|
107
|
+
addedThis = true;
|
106
108
|
}
|
107
|
-
|
109
|
+
result->append(simple);
|
108
110
|
}
|
109
|
-
|
110
|
-
|
111
|
-
|
111
|
+
|
112
|
+
if (!addedThis) {
|
113
|
+
result->append(this);
|
112
114
|
}
|
113
|
-
|
114
|
-
|
115
|
-
std::cerr << "> " << debug_call << " = Simple[" << this->to_string() << "]" << std::endl;
|
116
|
-
#endif
|
117
|
-
return this;
|
115
|
+
return result.detach();
|
116
|
+
|
118
117
|
}
|
118
|
+
// EO SimpleSelector::unifyWith(CompoundSelector*)
|
119
119
|
|
120
|
-
|
120
|
+
// ##########################################################################
|
121
|
+
// This is implemented in `selector/type.dart` as `PseudoSelector::unify`
|
122
|
+
// ##########################################################################
|
123
|
+
CompoundSelector* Type_Selector::unifyWith(CompoundSelector* rhs)
|
121
124
|
{
|
122
|
-
#ifdef DEBUG_UNIFY
|
123
|
-
const std::string debug_call = "unify(Type[" + this->to_string() + "], Compound[" + rhs->to_string() + "])";
|
124
|
-
std::cerr << debug_call << std::endl;
|
125
|
-
#endif
|
126
|
-
|
127
125
|
if (rhs->empty()) {
|
128
126
|
rhs->append(this);
|
129
|
-
#ifdef DEBUG_UNIFY
|
130
|
-
std::cerr << "> " << debug_call << " = Compound[" << rhs->to_string() << "]" << std::endl;
|
131
|
-
#endif
|
132
127
|
return rhs;
|
133
128
|
}
|
134
|
-
Type_Selector*
|
135
|
-
if (
|
136
|
-
|
129
|
+
Type_Selector* type = Cast<Type_Selector>(rhs->at(0));
|
130
|
+
if (type != nullptr) {
|
131
|
+
SimpleSelector* unified = unifyWith(type);
|
137
132
|
if (unified == nullptr) {
|
138
|
-
#ifdef DEBUG_UNIFY
|
139
|
-
std::cerr << "> " << debug_call << " = nullptr" << std::endl;
|
140
|
-
#endif
|
141
133
|
return nullptr;
|
142
134
|
}
|
143
135
|
rhs->elements()[0] = unified;
|
144
|
-
}
|
136
|
+
}
|
137
|
+
else if (!is_universal() || (has_ns_ && ns_ != "*")) {
|
145
138
|
rhs->insert(rhs->begin(), this);
|
146
139
|
}
|
147
|
-
#ifdef DEBUG_UNIFY
|
148
|
-
std::cerr << "> " << debug_call << " = Compound[" << rhs->to_string() << "]" << std::endl;
|
149
|
-
#endif
|
150
140
|
return rhs;
|
151
141
|
}
|
152
142
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
}
|
158
|
-
|
159
|
-
Compound_Selector* Id_Selector::unify_with(Compound_Selector* rhs)
|
143
|
+
// ##########################################################################
|
144
|
+
// This is implemented in `selector/id.dart` as `PseudoSelector::unify`
|
145
|
+
// ##########################################################################
|
146
|
+
CompoundSelector* Id_Selector::unifyWith(CompoundSelector* rhs)
|
160
147
|
{
|
161
|
-
for (const
|
162
|
-
if (Id_Selector* id_sel = Cast<Id_Selector>(sel)) {
|
148
|
+
for (const SimpleSelector* sel : rhs->elements()) {
|
149
|
+
if (const Id_Selector* id_sel = Cast<Id_Selector>(sel)) {
|
163
150
|
if (id_sel->name() != name()) return nullptr;
|
164
151
|
}
|
165
152
|
}
|
166
|
-
rhs
|
167
|
-
return Simple_Selector::unify_with(rhs);
|
168
|
-
}
|
169
|
-
|
170
|
-
Compound_Selector* Pseudo_Selector::unify_with(Compound_Selector* rhs)
|
171
|
-
{
|
172
|
-
if (is_pseudo_element()) {
|
173
|
-
for (const Simple_Selector_Obj& sel : rhs->elements()) {
|
174
|
-
if (Pseudo_Selector* pseudo_sel = Cast<Pseudo_Selector>(sel)) {
|
175
|
-
if (pseudo_sel->is_pseudo_element() && pseudo_sel->name() != name()) return nullptr;
|
176
|
-
}
|
177
|
-
}
|
178
|
-
}
|
179
|
-
return Simple_Selector::unify_with(rhs);
|
153
|
+
return SimpleSelector::unifyWith(rhs);
|
180
154
|
}
|
181
155
|
|
182
|
-
|
156
|
+
// ##########################################################################
|
157
|
+
// This is implemented in `selector/pseudo.dart` as `PseudoSelector::unify`
|
158
|
+
// ##########################################################################
|
159
|
+
CompoundSelector* Pseudo_Selector::unifyWith(CompoundSelector* compound)
|
183
160
|
{
|
184
|
-
#ifdef DEBUG_UNIFY
|
185
|
-
const std::string debug_call = "unify(Complex[" + this->to_string() + "], Complex[" + rhs->to_string() + "])";
|
186
|
-
std::cerr << debug_call << std::endl;
|
187
|
-
#endif
|
188
|
-
|
189
|
-
// get last tails (on the right side)
|
190
|
-
Complex_Selector* l_last = this->mutable_last();
|
191
|
-
Complex_Selector* r_last = rhs->mutable_last();
|
192
|
-
|
193
|
-
// check valid pointers (assertion)
|
194
|
-
SASS_ASSERT(l_last, "lhs is null");
|
195
|
-
SASS_ASSERT(r_last, "rhs is null");
|
196
|
-
|
197
|
-
// Not sure about this check, but closest way I could check
|
198
|
-
// was to see if this is a ruby 'SimpleSequence' equivalent.
|
199
|
-
// It seems to do the job correctly as some specs react to this
|
200
|
-
if (l_last->combinator() != Combinator::ANCESTOR_OF) return nullptr;
|
201
|
-
if (r_last->combinator() != Combinator::ANCESTOR_OF) return nullptr;
|
202
|
-
|
203
|
-
// get the headers for the last tails
|
204
|
-
Compound_Selector* l_last_head = l_last->head();
|
205
|
-
Compound_Selector* r_last_head = r_last->head();
|
206
|
-
|
207
|
-
// check valid head pointers (assertion)
|
208
|
-
SASS_ASSERT(l_last_head, "lhs head is null");
|
209
|
-
SASS_ASSERT(r_last_head, "rhs head is null");
|
210
|
-
|
211
|
-
// get the unification of the last compound selectors
|
212
|
-
Compound_Selector_Obj unified = r_last_head->unify_with(l_last_head);
|
213
|
-
|
214
|
-
// abort if we could not unify heads
|
215
|
-
if (unified == nullptr) return nullptr;
|
216
|
-
|
217
|
-
// move the head
|
218
|
-
if (l_last_head->is_universal()) l_last->head({});
|
219
|
-
r_last->head(unified);
|
220
161
|
|
221
|
-
|
222
|
-
|
223
|
-
|
162
|
+
if (compound->length() == 1 && compound->first()->is_universal()) {
|
163
|
+
// std::cerr << "implement universal pseudo\n";
|
164
|
+
}
|
224
165
|
|
225
|
-
|
226
|
-
|
227
|
-
|
166
|
+
for (const SimpleSelectorObj& sel : compound->elements()) {
|
167
|
+
if (*this == *sel) {
|
168
|
+
return compound;
|
169
|
+
}
|
170
|
+
}
|
228
171
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
172
|
+
CompoundSelectorObj result = SASS_MEMORY_NEW(CompoundSelector, compound->pstate());
|
173
|
+
|
174
|
+
bool addedThis = false;
|
175
|
+
for (auto simple : compound->elements()) {
|
176
|
+
// Make sure pseudo selectors always come last.
|
177
|
+
if (Pseudo_Selector_Obj pseudo = simple->getPseudoSelector()) {
|
178
|
+
if (pseudo->isElement()) {
|
179
|
+
// A given compound selector may only contain one pseudo element. If
|
180
|
+
// [compound] has a different one than [this], unification fails.
|
181
|
+
if (isElement()) {
|
182
|
+
return {};
|
183
|
+
}
|
184
|
+
// Otherwise, this is a pseudo selector and
|
185
|
+
// should come before pseduo elements.
|
186
|
+
result->append(this);
|
187
|
+
addedThis = true;
|
188
|
+
}
|
189
|
+
}
|
190
|
+
result->append(simple);
|
191
|
+
}
|
233
192
|
|
234
|
-
|
235
|
-
|
236
|
-
Selector_List_Obj result = SASS_MEMORY_NEW(Selector_List, pstate(), node.collection()->size());
|
237
|
-
for (auto &item : *node.collection()) {
|
238
|
-
result->append(nodeToComplexSelector(Node::naiveTrim(item)));
|
193
|
+
if (!addedThis) {
|
194
|
+
result->append(this);
|
239
195
|
}
|
240
196
|
|
241
|
-
|
242
|
-
std::cerr << "> " << debug_call << " = " << result->to_string() << std::endl;
|
243
|
-
#endif
|
197
|
+
return result.detach();
|
244
198
|
|
245
|
-
// only return if list has some entries
|
246
|
-
return result->length() ? result.detach() : nullptr;
|
247
199
|
}
|
200
|
+
// EO Pseudo_Selector::unifyWith(CompoundSelector*
|
201
|
+
|
202
|
+
// ##########################################################################
|
203
|
+
// This is implemented in `extend/functions.dart` as `unifyUniversalAndElement`
|
204
|
+
// Returns a [SimpleSelector] that matches only elements that are matched by
|
205
|
+
// both [selector1] and [selector2], which must both be either [UniversalSelector]s
|
206
|
+
// or [TypeSelector]s. If no such selector can be produced, returns `null`.
|
207
|
+
// Note: libsass handles universal selector directly within the type selector
|
208
|
+
// ##########################################################################
|
209
|
+
SimpleSelector* Type_Selector::unifyWith(const SimpleSelector* rhs)
|
210
|
+
{
|
211
|
+
bool rhs_ns = false;
|
212
|
+
if (!(is_ns_eq(*rhs) || rhs->is_universal_ns())) {
|
213
|
+
if (!is_universal_ns()) {
|
214
|
+
return nullptr;
|
215
|
+
}
|
216
|
+
rhs_ns = true;
|
217
|
+
}
|
218
|
+
bool rhs_name = false;
|
219
|
+
if (!(name_ == rhs->name() || rhs->is_universal())) {
|
220
|
+
if (!(is_universal())) {
|
221
|
+
return nullptr;
|
222
|
+
}
|
223
|
+
rhs_name = true;
|
224
|
+
}
|
225
|
+
if (rhs_ns) {
|
226
|
+
ns(rhs->ns());
|
227
|
+
has_ns(rhs->has_ns());
|
228
|
+
}
|
229
|
+
if (rhs_name) name(rhs->name());
|
230
|
+
return this;
|
231
|
+
}
|
232
|
+
// EO Type_Selector::unifyWith(const SimpleSelector*)
|
248
233
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
234
|
+
// ##########################################################################
|
235
|
+
// Unify two complex selectors. Internally calls `unifyComplex`
|
236
|
+
// and then wraps the result in newly create ComplexSelectors.
|
237
|
+
// ##########################################################################
|
238
|
+
SelectorList* ComplexSelector::unifyWith(ComplexSelector* rhs)
|
239
|
+
{
|
240
|
+
SelectorListObj list = SASS_MEMORY_NEW(SelectorList, pstate());
|
241
|
+
std::vector<std::vector<SelectorComponentObj>> rv =
|
242
|
+
unifyComplex({ elements(), rhs->elements() });
|
243
|
+
for (std::vector<SelectorComponentObj> items : rv) {
|
244
|
+
ComplexSelectorObj sel = SASS_MEMORY_NEW(ComplexSelector, pstate());
|
245
|
+
sel->elements() = std::move(items);
|
246
|
+
list->append(sel);
|
247
|
+
}
|
248
|
+
return list.detach();
|
249
|
+
}
|
250
|
+
// EO ComplexSelector::unifyWith(ComplexSelector*)
|
254
251
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
252
|
+
// ##########################################################################
|
253
|
+
// only called from the sass function `selector-unify`
|
254
|
+
// ##########################################################################
|
255
|
+
SelectorList* SelectorList::unifyWith(SelectorList* rhs)
|
256
|
+
{
|
257
|
+
SelectorList* slist = SASS_MEMORY_NEW(SelectorList, pstate());
|
258
|
+
// Unify all of children with RHS's children,
|
259
|
+
// storing the results in `unified_complex_selectors`
|
260
|
+
for (ComplexSelectorObj& seq1 : elements()) {
|
261
|
+
for (ComplexSelectorObj& seq2 : rhs->elements()) {
|
262
|
+
if (SelectorListObj unified = seq1->unifyWith(seq2)) {
|
263
|
+
std::move(unified->begin(), unified->end(),
|
264
|
+
std::inserter(slist->elements(), slist->end()));
|
265
265
|
}
|
266
266
|
}
|
267
267
|
}
|
268
|
-
|
269
|
-
// Creates the final Selector_List by combining all the complex selectors
|
270
|
-
Selector_List* final_result = SASS_MEMORY_NEW(Selector_List, pstate(), result.size());
|
271
|
-
for (Complex_Selector_Obj& sel : result) {
|
272
|
-
final_result->append(sel);
|
273
|
-
}
|
274
|
-
#ifdef DEBUG_UNIFY
|
275
|
-
std::cerr << "> " << debug_call << " = " << final_result->to_string() << std::endl;
|
276
|
-
#endif
|
277
|
-
return final_result;
|
268
|
+
return slist;
|
278
269
|
}
|
270
|
+
// EO SelectorList::unifyWith(SelectorList*)
|
271
|
+
|
272
|
+
// ##########################################################################
|
273
|
+
// ##########################################################################
|
279
274
|
|
280
275
|
}
|