sassc 2.2.1 → 2.3.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 +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
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// sass.hpp must go before all system headers to get the
|
|
2
|
+
// __EXTENSIONS__ fix on Solaris.
|
|
3
|
+
#include "sass.hpp"
|
|
4
|
+
#include "expand.hpp"
|
|
5
|
+
#include "eval.hpp"
|
|
6
|
+
#include "ast.hpp"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
namespace Sass {
|
|
10
|
+
|
|
11
|
+
SelectorList* Eval::operator()(SelectorList* s)
|
|
12
|
+
{
|
|
13
|
+
std::vector<SelectorListObj> rv;
|
|
14
|
+
SelectorListObj sl = SASS_MEMORY_NEW(SelectorList, s->pstate());
|
|
15
|
+
for (size_t i = 0, iL = s->length(); i < iL; ++i) {
|
|
16
|
+
rv.push_back(operator()(s->get(i)));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// we should actually permutate parent first
|
|
20
|
+
// but here we have permutated the selector first
|
|
21
|
+
size_t round = 0;
|
|
22
|
+
while (round != std::string::npos) {
|
|
23
|
+
bool abort = true;
|
|
24
|
+
for (size_t i = 0, iL = rv.size(); i < iL; ++i) {
|
|
25
|
+
if (rv[i]->length() > round) {
|
|
26
|
+
sl->append((*rv[i])[round]);
|
|
27
|
+
abort = false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (abort) {
|
|
31
|
+
round = std::string::npos;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
++round;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
}
|
|
38
|
+
return sl.detach();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
SelectorComponent* Eval::operator()(SelectorComponent* s)
|
|
42
|
+
{
|
|
43
|
+
return {};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
SelectorList* Eval::operator()(ComplexSelector* s)
|
|
47
|
+
{
|
|
48
|
+
bool implicit_parent = !exp.old_at_root_without_rule;
|
|
49
|
+
if (is_in_selector_schema) exp.pushNullSelector();
|
|
50
|
+
SelectorListObj other = s->resolve_parent_refs(
|
|
51
|
+
exp.getOriginalStack(), traces, implicit_parent);
|
|
52
|
+
if (is_in_selector_schema) exp.popNullSelector();
|
|
53
|
+
|
|
54
|
+
for (size_t i = 0; i < other->length(); i++) {
|
|
55
|
+
ComplexSelectorObj sel = other->at(i);
|
|
56
|
+
for (size_t n = 0; n < sel->length(); n++) {
|
|
57
|
+
if (CompoundSelectorObj comp = Cast<CompoundSelector>(sel->at(n))) {
|
|
58
|
+
sel->at(n) = operator()(comp);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return other.detach();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
CompoundSelector* Eval::operator()(CompoundSelector* s)
|
|
67
|
+
{
|
|
68
|
+
for (size_t i = 0; i < s->length(); i++) {
|
|
69
|
+
SimpleSelector* ss = s->at(i);
|
|
70
|
+
// skip parents here (called via resolve_parent_refs)
|
|
71
|
+
s->at(i) = Cast<SimpleSelector>(ss->perform(this));
|
|
72
|
+
}
|
|
73
|
+
return s;
|
|
74
|
+
}
|
|
75
|
+
}
|
data/ext/libsass/src/expand.cpp
CHANGED
|
@@ -19,7 +19,7 @@ namespace Sass {
|
|
|
19
19
|
// simple endless recursion protection
|
|
20
20
|
const size_t maxRecursion = 500;
|
|
21
21
|
|
|
22
|
-
Expand::Expand(Context& ctx, Env* env, SelectorStack* stack)
|
|
22
|
+
Expand::Expand(Context& ctx, Env* env, SelectorStack* stack, SelectorStack* originals)
|
|
23
23
|
: ctx(ctx),
|
|
24
24
|
traces(ctx.traces),
|
|
25
25
|
eval(Eval(*this)),
|
|
@@ -27,19 +27,32 @@ namespace Sass {
|
|
|
27
27
|
in_keyframes(false),
|
|
28
28
|
at_root_without_rule(false),
|
|
29
29
|
old_at_root_without_rule(false),
|
|
30
|
-
env_stack(
|
|
31
|
-
block_stack(
|
|
32
|
-
call_stack(
|
|
33
|
-
selector_stack(
|
|
34
|
-
|
|
30
|
+
env_stack(),
|
|
31
|
+
block_stack(),
|
|
32
|
+
call_stack(),
|
|
33
|
+
selector_stack(),
|
|
34
|
+
originalStack(),
|
|
35
|
+
mediaStack()
|
|
35
36
|
{
|
|
36
37
|
env_stack.push_back(nullptr);
|
|
37
38
|
env_stack.push_back(env);
|
|
38
39
|
block_stack.push_back(nullptr);
|
|
39
40
|
call_stack.push_back({});
|
|
40
|
-
if (stack == NULL) {
|
|
41
|
-
else {
|
|
42
|
-
|
|
41
|
+
if (stack == NULL) { pushToSelectorStack({}); }
|
|
42
|
+
else {
|
|
43
|
+
for (auto item : *stack) {
|
|
44
|
+
if (item.isNull()) pushToSelectorStack({});
|
|
45
|
+
else pushToSelectorStack(item);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (originals == NULL) { pushToOriginalStack({}); }
|
|
49
|
+
else {
|
|
50
|
+
for (auto item : *stack) {
|
|
51
|
+
if (item.isNull()) pushToOriginalStack({});
|
|
52
|
+
else pushToOriginalStack(item);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
mediaStack.push_back({});
|
|
43
56
|
}
|
|
44
57
|
|
|
45
58
|
Env* Expand::environment()
|
|
@@ -49,11 +62,80 @@ namespace Sass {
|
|
|
49
62
|
return 0;
|
|
50
63
|
}
|
|
51
64
|
|
|
52
|
-
|
|
65
|
+
void Expand::pushNullSelector()
|
|
66
|
+
{
|
|
67
|
+
pushToSelectorStack({});
|
|
68
|
+
pushToOriginalStack({});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
void Expand::popNullSelector()
|
|
72
|
+
{
|
|
73
|
+
popFromOriginalStack();
|
|
74
|
+
popFromSelectorStack();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
SelectorStack Expand::getOriginalStack()
|
|
78
|
+
{
|
|
79
|
+
return originalStack;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
SelectorStack Expand::getSelectorStack()
|
|
53
83
|
{
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
84
|
+
return selector_stack;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
SelectorListObj& Expand::selector()
|
|
88
|
+
{
|
|
89
|
+
if (selector_stack.size() > 0) {
|
|
90
|
+
auto& sel = selector_stack.back();
|
|
91
|
+
if (sel.isNull()) return sel;
|
|
92
|
+
return sel;
|
|
93
|
+
}
|
|
94
|
+
// Avoid the need to return copies
|
|
95
|
+
// We always want an empty first item
|
|
96
|
+
selector_stack.push_back({});
|
|
97
|
+
return selector_stack.back();;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
SelectorListObj& Expand::original()
|
|
101
|
+
{
|
|
102
|
+
if (originalStack.size() > 0) {
|
|
103
|
+
auto& sel = originalStack.back();
|
|
104
|
+
if (sel.isNull()) return sel;
|
|
105
|
+
return sel;
|
|
106
|
+
}
|
|
107
|
+
// Avoid the need to return copies
|
|
108
|
+
// We always want an empty first item
|
|
109
|
+
originalStack.push_back({});
|
|
110
|
+
return originalStack.back();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
SelectorListObj Expand::popFromSelectorStack()
|
|
114
|
+
{
|
|
115
|
+
SelectorListObj last = selector_stack.back();
|
|
116
|
+
if (selector_stack.size() > 0)
|
|
117
|
+
selector_stack.pop_back();
|
|
118
|
+
if (last.isNull()) return {};
|
|
119
|
+
return last;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
void Expand::pushToSelectorStack(SelectorListObj selector)
|
|
123
|
+
{
|
|
124
|
+
selector_stack.push_back(selector);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
SelectorListObj Expand::popFromOriginalStack()
|
|
128
|
+
{
|
|
129
|
+
SelectorListObj last = originalStack.back();
|
|
130
|
+
if (originalStack.size() > 0)
|
|
131
|
+
originalStack.pop_back();
|
|
132
|
+
if (last.isNull()) return {};
|
|
133
|
+
return last;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
void Expand::pushToOriginalStack(SelectorListObj selector)
|
|
137
|
+
{
|
|
138
|
+
originalStack.push_back(selector);
|
|
57
139
|
}
|
|
58
140
|
|
|
59
141
|
// blocks create new variable scopes
|
|
@@ -87,69 +169,55 @@ namespace Sass {
|
|
|
87
169
|
if (in_keyframes) {
|
|
88
170
|
Block* bb = operator()(r->block());
|
|
89
171
|
Keyframe_Rule_Obj k = SASS_MEMORY_NEW(Keyframe_Rule, r->pstate(), bb);
|
|
90
|
-
if (r->
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
172
|
+
if (r->schema()) {
|
|
173
|
+
pushNullSelector();
|
|
174
|
+
k->name(eval(r->schema()));
|
|
175
|
+
popNullSelector();
|
|
176
|
+
}
|
|
177
|
+
else if (r->selector()) {
|
|
178
|
+
if (SelectorListObj s = r->selector()) {
|
|
179
|
+
pushNullSelector();
|
|
180
|
+
k->name(eval(s));
|
|
181
|
+
popNullSelector();
|
|
95
182
|
}
|
|
96
183
|
}
|
|
184
|
+
|
|
97
185
|
return k.detach();
|
|
98
186
|
}
|
|
99
187
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
Selector_List_Obj ll = selector_stack.at(i);
|
|
107
|
-
has_parent_selector = ll != nullptr && ll->length() > 0;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
Selector_List_Obj sel = r->selector();
|
|
111
|
-
if (sel) sel = sel->eval(eval);
|
|
112
|
-
|
|
113
|
-
// check for parent selectors in base level rules
|
|
114
|
-
if (r->is_root() || (block_stack.back() && block_stack.back()->is_root())) {
|
|
115
|
-
if (Selector_List* selector_list = Cast<Selector_List>(r->selector())) {
|
|
116
|
-
for (Complex_Selector_Obj complex_selector : selector_list->elements()) {
|
|
117
|
-
Complex_Selector* tail = complex_selector;
|
|
118
|
-
while (tail) {
|
|
119
|
-
if (tail->head()) for (Simple_Selector_Obj header : tail->head()->elements()) {
|
|
120
|
-
Parent_Selector* ptr = Cast<Parent_Selector>(header);
|
|
121
|
-
if (ptr == NULL || (!ptr->real() || has_parent_selector)) continue;
|
|
122
|
-
std::string sel_str(complex_selector->to_string(ctx.c_options));
|
|
123
|
-
error("Base-level rules cannot contain the parent-selector-referencing character '&'.", header->pstate(), traces);
|
|
124
|
-
}
|
|
125
|
-
tail = tail->tail();
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
if (sel->length() == 0 || sel->has_parent_ref()) {
|
|
132
|
-
if (sel->has_real_parent_ref() && !has_parent_selector) {
|
|
133
|
-
error("Base-level rules cannot contain the parent-selector-referencing character '&'.", sel->pstate(), traces);
|
|
134
|
-
}
|
|
188
|
+
if (r->schema()) {
|
|
189
|
+
SelectorListObj sel = eval(r->schema());
|
|
190
|
+
r->selector(sel);
|
|
191
|
+
bool chroot = sel->has_real_parent_ref();
|
|
192
|
+
for (auto complex : sel->elements()) {
|
|
193
|
+
complex->chroots(chroot);
|
|
135
194
|
}
|
|
195
|
+
|
|
136
196
|
}
|
|
137
197
|
|
|
198
|
+
// reset when leaving scope
|
|
199
|
+
LOCAL_FLAG(at_root_without_rule, false);
|
|
200
|
+
|
|
201
|
+
SelectorListObj evaled = eval(r->selector());
|
|
138
202
|
// do not connect parent again
|
|
139
|
-
sel->remove_parent_selectors();
|
|
140
|
-
selector_stack.push_back(sel);
|
|
141
203
|
Env env(environment());
|
|
142
204
|
if (block_stack.back()->is_root()) {
|
|
143
205
|
env_stack.push_back(&env);
|
|
144
206
|
}
|
|
145
|
-
sel->set_media_block(media_stack.back());
|
|
146
207
|
Block_Obj blk;
|
|
208
|
+
pushToSelectorStack(evaled);
|
|
209
|
+
// The copy is needed for parent reference evaluation
|
|
210
|
+
// dart-sass stores it as `originalSelector` member
|
|
211
|
+
pushToOriginalStack(SASS_MEMORY_COPY(evaled));
|
|
212
|
+
ctx.extender.addSelector(evaled, mediaStack.back());
|
|
147
213
|
if (r->block()) blk = operator()(r->block());
|
|
214
|
+
popFromOriginalStack();
|
|
215
|
+
popFromSelectorStack();
|
|
148
216
|
Ruleset* rr = SASS_MEMORY_NEW(Ruleset,
|
|
149
217
|
r->pstate(),
|
|
150
|
-
|
|
218
|
+
evaled,
|
|
151
219
|
blk);
|
|
152
|
-
|
|
220
|
+
|
|
153
221
|
if (block_stack.back()->is_root()) {
|
|
154
222
|
env_stack.pop_back();
|
|
155
223
|
}
|
|
@@ -170,31 +238,44 @@ namespace Sass {
|
|
|
170
238
|
return ff.detach();
|
|
171
239
|
}
|
|
172
240
|
|
|
173
|
-
|
|
241
|
+
std::vector<CssMediaQuery_Obj> Expand::mergeMediaQueries(
|
|
242
|
+
const std::vector<CssMediaQuery_Obj>& lhs,
|
|
243
|
+
const std::vector<CssMediaQuery_Obj>& rhs)
|
|
174
244
|
{
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
245
|
+
std::vector<CssMediaQuery_Obj> queries;
|
|
246
|
+
for (CssMediaQuery_Obj query1 : lhs) {
|
|
247
|
+
for (CssMediaQuery_Obj query2 : rhs) {
|
|
248
|
+
CssMediaQuery_Obj result = query1->merge(query2);
|
|
249
|
+
if (result && !result->empty()) {
|
|
250
|
+
queries.push_back(result);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return queries;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
Statement* Expand::operator()(MediaRule* m)
|
|
258
|
+
{
|
|
259
|
+
Expression_Obj mq = eval(m->schema());
|
|
260
|
+
std::string str_mq(mq->to_css(ctx.c_options));
|
|
184
261
|
char* str = sass_copy_c_string(str_mq.c_str());
|
|
185
262
|
ctx.strings.push_back(str);
|
|
186
|
-
Parser
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
263
|
+
Parser parser(Parser::from_c_str(str, ctx, traces, mq->pstate()));
|
|
264
|
+
// Create a new CSS only representation of the media rule
|
|
265
|
+
CssMediaRuleObj css = SASS_MEMORY_NEW(CssMediaRule, m->pstate(), m->block());
|
|
266
|
+
std::vector<CssMediaQuery_Obj> parsed = parser.parseCssMediaQueries();
|
|
267
|
+
if (mediaStack.size() && mediaStack.back()) {
|
|
268
|
+
auto& parent = mediaStack.back()->elements();
|
|
269
|
+
css->concat(mergeMediaQueries(parent, parsed));
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
css->concat(parsed);
|
|
273
|
+
}
|
|
274
|
+
mediaStack.push_back(css);
|
|
275
|
+
css->block(operator()(m->block()));
|
|
276
|
+
mediaStack.pop_back();
|
|
277
|
+
return css.detach();
|
|
278
|
+
|
|
198
279
|
}
|
|
199
280
|
|
|
200
281
|
Statement* Expand::operator()(At_Root_Block* a)
|
|
@@ -222,12 +303,12 @@ namespace Sass {
|
|
|
222
303
|
{
|
|
223
304
|
LOCAL_FLAG(in_keyframes, a->is_keyframes());
|
|
224
305
|
Block* ab = a->block();
|
|
225
|
-
|
|
306
|
+
SelectorList* as = a->selector();
|
|
226
307
|
Expression* av = a->value();
|
|
227
|
-
|
|
308
|
+
pushNullSelector();
|
|
228
309
|
if (av) av = av->perform(&eval);
|
|
229
310
|
if (as) as = eval(as);
|
|
230
|
-
|
|
311
|
+
popNullSelector();
|
|
231
312
|
Block* bb = ab ? operator()(ab) : NULL;
|
|
232
313
|
Directive* aa = SASS_MEMORY_NEW(Directive,
|
|
233
314
|
a->pstate(),
|
|
@@ -497,9 +578,8 @@ namespace Sass {
|
|
|
497
578
|
if (expr->concrete_type() == Expression::MAP) {
|
|
498
579
|
map = Cast<Map>(expr);
|
|
499
580
|
}
|
|
500
|
-
else if (
|
|
501
|
-
Listize
|
|
502
|
-
Expression_Obj rv = ls->perform(&listize);
|
|
581
|
+
else if (SelectorList * ls = Cast<SelectorList>(expr)) {
|
|
582
|
+
Expression_Obj rv = Listize::perform(ls);
|
|
503
583
|
list = Cast<List>(rv);
|
|
504
584
|
}
|
|
505
585
|
else if (expr->concrete_type() != Expression::LIST) {
|
|
@@ -534,7 +614,7 @@ namespace Sass {
|
|
|
534
614
|
}
|
|
535
615
|
else {
|
|
536
616
|
// bool arglist = list->is_arglist();
|
|
537
|
-
if (list->length() == 1 && Cast<
|
|
617
|
+
if (list->length() == 1 && Cast<SelectorList>(list)) {
|
|
538
618
|
list = Cast<List>(list);
|
|
539
619
|
}
|
|
540
620
|
for (size_t i = 0, L = list->length(); i < L; ++i) {
|
|
@@ -595,87 +675,63 @@ namespace Sass {
|
|
|
595
675
|
return 0;
|
|
596
676
|
}
|
|
597
677
|
|
|
678
|
+
Statement* Expand::operator()(ExtendRule* e)
|
|
679
|
+
{
|
|
598
680
|
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
Complex_Selector_Obj tail = complex_selector;
|
|
604
|
-
while (tail) {
|
|
605
|
-
if (tail->head()) for (Simple_Selector_Obj header : tail->head()->elements()) {
|
|
606
|
-
if (Cast<Parent_Selector>(header) == NULL) continue; // skip all others
|
|
607
|
-
std::string sel_str(complex_selector->to_string(ctx.c_options));
|
|
608
|
-
error("Can't extend " + sel_str + ": can't extend parent selectors", header->pstate(), traces);
|
|
609
|
-
}
|
|
610
|
-
tail = tail->tail();
|
|
611
|
-
}
|
|
612
|
-
}
|
|
681
|
+
// evaluate schema first
|
|
682
|
+
if (e->schema()) {
|
|
683
|
+
e->selector(eval(e->schema()));
|
|
684
|
+
e->isOptional(e->selector()->is_optional());
|
|
613
685
|
}
|
|
686
|
+
// evaluate the selector
|
|
687
|
+
e->selector(eval(e->selector()));
|
|
614
688
|
|
|
689
|
+
if (e->selector()) {
|
|
615
690
|
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
if (!c->head() || c->tail()) {
|
|
621
|
-
std::string sel_str(contextualized->to_string(ctx.c_options));
|
|
622
|
-
error("Can't extend " + sel_str + ": can't extend nested selectors", c->pstate(), traces);
|
|
623
|
-
}
|
|
624
|
-
Compound_Selector_Obj target = c->head();
|
|
625
|
-
if (contextualized->is_optional()) target->is_optional(true);
|
|
626
|
-
for (size_t i = 0, L = extender->length(); i < L; ++i) {
|
|
627
|
-
Complex_Selector_Obj sel = (*extender)[i];
|
|
628
|
-
if (!(sel->head() && sel->head()->length() > 0 &&
|
|
629
|
-
Cast<Parent_Selector>((*sel->head())[0])))
|
|
630
|
-
{
|
|
631
|
-
Compound_Selector_Obj hh = SASS_MEMORY_NEW(Compound_Selector, (*extender)[i]->pstate());
|
|
632
|
-
hh->media_block((*extender)[i]->media_block());
|
|
633
|
-
Complex_Selector_Obj ssel = SASS_MEMORY_NEW(Complex_Selector, (*extender)[i]->pstate());
|
|
634
|
-
ssel->media_block((*extender)[i]->media_block());
|
|
635
|
-
if (sel->has_line_feed()) ssel->has_line_feed(true);
|
|
636
|
-
Parent_Selector_Obj ps = SASS_MEMORY_NEW(Parent_Selector, (*extender)[i]->pstate());
|
|
637
|
-
ps->media_block((*extender)[i]->media_block());
|
|
638
|
-
hh->append(ps);
|
|
639
|
-
ssel->tail(sel);
|
|
640
|
-
ssel->head(hh);
|
|
641
|
-
sel = ssel;
|
|
691
|
+
for (auto complex : e->selector()->elements()) {
|
|
692
|
+
|
|
693
|
+
if (complex->length() != 1) {
|
|
694
|
+
error("complex selectors may not be extended.", complex->pstate(), traces);
|
|
642
695
|
}
|
|
643
|
-
// if (c->has_line_feed()) sel->has_line_feed(true);
|
|
644
|
-
ctx.subset_map.put(target, std::make_pair(sel, target));
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
696
|
|
|
648
|
-
|
|
697
|
+
if (const CompoundSelector* compound = complex->first()->getCompound()) {
|
|
698
|
+
|
|
699
|
+
if (compound->length() != 1) {
|
|
700
|
+
|
|
701
|
+
std::stringstream sels; bool addComma = false;
|
|
702
|
+
sels << "Compound selectors may no longer be extended.\n";
|
|
703
|
+
sels << "Consider `@extend ";
|
|
704
|
+
for (auto sel : compound->elements()) {
|
|
705
|
+
if (addComma) sels << ", ";
|
|
706
|
+
sels << sel->to_sass();
|
|
707
|
+
addComma = true;
|
|
708
|
+
}
|
|
709
|
+
sels << "` instead.\n";
|
|
710
|
+
sels << "See http://bit.ly/ExtendCompound for details.";
|
|
711
|
+
|
|
712
|
+
warning(sels.str(), compound->pstate());
|
|
713
|
+
|
|
714
|
+
// Make this an error once deprecation is over
|
|
715
|
+
for (SimpleSelectorObj simple : compound->elements()) {
|
|
716
|
+
// Pass every selector we ever see to extender (to make them findable for extend)
|
|
717
|
+
ctx.extender.addExtension(selector(), simple, mediaStack.back(), e->isOptional());
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
}
|
|
721
|
+
else {
|
|
722
|
+
// Pass every selector we ever see to extender (to make them findable for extend)
|
|
723
|
+
ctx.extender.addExtension(selector(), compound->first(), mediaStack.back(), e->isOptional());
|
|
724
|
+
}
|
|
649
725
|
|
|
650
|
-
Statement* Expand::operator()(Extension* e)
|
|
651
|
-
{
|
|
652
|
-
if (Selector_List_Obj extender = selector()) {
|
|
653
|
-
Selector_List* sl = e->selector();
|
|
654
|
-
// abort on invalid selector
|
|
655
|
-
if (sl == NULL) return NULL;
|
|
656
|
-
if (Selector_Schema* schema = sl->schema()) {
|
|
657
|
-
if (schema->has_real_parent_ref()) {
|
|
658
|
-
// put root block on stack again (ignore parents)
|
|
659
|
-
// selector schema must not connect in eval!
|
|
660
|
-
block_stack.push_back(block_stack.at(1));
|
|
661
|
-
sl = eval(sl->schema());
|
|
662
|
-
block_stack.pop_back();
|
|
663
|
-
} else {
|
|
664
|
-
selector_stack.push_back({});
|
|
665
|
-
sl = eval(sl->schema());
|
|
666
|
-
selector_stack.pop_back();
|
|
667
726
|
}
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
if (!cs.isNull() && !cs->head().isNull()) {
|
|
671
|
-
cs->head()->media_block(media_stack.back());
|
|
727
|
+
else {
|
|
728
|
+
error("complex selectors may not be extended.", complex->pstate(), traces);
|
|
672
729
|
}
|
|
673
730
|
}
|
|
674
|
-
selector_stack.push_back({});
|
|
675
|
-
expand_selector_list(sl, extender);
|
|
676
|
-
selector_stack.pop_back();
|
|
677
731
|
}
|
|
678
|
-
|
|
732
|
+
|
|
733
|
+
return nullptr;
|
|
734
|
+
|
|
679
735
|
}
|
|
680
736
|
|
|
681
737
|
Statement* Expand::operator()(Definition* d)
|
|
@@ -705,6 +761,7 @@ namespace Sass {
|
|
|
705
761
|
|
|
706
762
|
Statement* Expand::operator()(Mixin_Call* c)
|
|
707
763
|
{
|
|
764
|
+
|
|
708
765
|
if (recursions > maxRecursion) {
|
|
709
766
|
throw Exception::StackError(traces, *c);
|
|
710
767
|
}
|
|
@@ -785,11 +842,6 @@ namespace Sass {
|
|
|
785
842
|
Env* env = environment();
|
|
786
843
|
// convert @content directives into mixin calls to the underlying thunk
|
|
787
844
|
if (!env->has("@content[m]")) return 0;
|
|
788
|
-
|
|
789
|
-
if (block_stack.back()->is_root()) {
|
|
790
|
-
selector_stack.push_back({});
|
|
791
|
-
}
|
|
792
|
-
|
|
793
845
|
Arguments_Obj args = c->arguments();
|
|
794
846
|
if (!args) args = SASS_MEMORY_NEW(Arguments, c->pstate());
|
|
795
847
|
|
|
@@ -799,11 +851,6 @@ namespace Sass {
|
|
|
799
851
|
args);
|
|
800
852
|
|
|
801
853
|
Trace_Obj trace = Cast<Trace>(call->perform(this));
|
|
802
|
-
|
|
803
|
-
if (block_stack.back()->is_root()) {
|
|
804
|
-
selector_stack.pop_back();
|
|
805
|
-
}
|
|
806
|
-
|
|
807
854
|
return trace.detach();
|
|
808
855
|
}
|
|
809
856
|
|