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,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
|
+
sass::vector<sass::vector<SelectorComponentObj>> unifyComplex(
|
17
|
+
const sass::vector<sass::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, SourceSpan("[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
|
+
sass::vector<sass::vector<SelectorComponentObj>> complexesWithoutBases;
|
43
|
+
for (size_t i = 0; i < complexes.size(); i += 1) {
|
44
|
+
sass::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* TypeSelector::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
|
-
|
135
|
-
if (
|
136
|
-
|
129
|
+
TypeSelector* type = Cast<TypeSelector>(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* IDSelector::unifyWith(CompoundSelector* rhs)
|
160
147
|
{
|
161
|
-
for (const
|
162
|
-
if (
|
148
|
+
for (const SimpleSelector* sel : rhs->elements()) {
|
149
|
+
if (const IDSelector* id_sel = Cast<IDSelector>(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* PseudoSelector::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 (PseudoSelectorObj 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 PseudoSelector::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* TypeSelector::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 TypeSelector::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
|
+
sass::vector<sass::vector<SelectorComponentObj>> rv =
|
242
|
+
unifyComplex({ elements(), rhs->elements() });
|
243
|
+
for (sass::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
|
}
|