sassc 1.9.0 → 1.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +30 -3
- data/ext/libsass/.gitignore +3 -0
- data/ext/libsass/.travis.yml +1 -1
- data/ext/libsass/GNUmakefile.am +7 -7
- data/ext/libsass/Makefile +7 -4
- data/ext/libsass/Makefile.conf +0 -1
- data/ext/libsass/appveyor.yml +6 -2
- data/ext/libsass/docs/api-context.md +4 -4
- data/ext/libsass/docs/api-doc.md +29 -11
- data/ext/libsass/docs/api-importer-example.md +5 -5
- data/ext/libsass/docs/build-on-windows.md +1 -1
- data/ext/libsass/include/sass/base.h +10 -0
- data/ext/libsass/include/sass/version.h +4 -0
- data/ext/libsass/include/sass/version.h.in +4 -0
- data/ext/libsass/include/sass2scss.h +1 -1
- data/ext/libsass/script/ci-build-libsass +15 -3
- data/ext/libsass/src/ast.cpp +161 -6
- data/ext/libsass/src/ast.hpp +71 -44
- data/ext/libsass/src/ast_factory.hpp +1 -1
- data/ext/libsass/src/ast_fwd_decl.hpp +2 -2
- data/ext/libsass/src/constants.cpp +2 -4
- data/ext/libsass/src/constants.hpp +3 -4
- data/ext/libsass/src/context.cpp +16 -17
- data/ext/libsass/src/context.hpp +2 -2
- data/ext/libsass/src/cssize.cpp +19 -8
- data/ext/libsass/src/cssize.hpp +5 -2
- data/ext/libsass/src/debugger.hpp +6 -3
- data/ext/libsass/src/emitter.cpp +1 -1
- data/ext/libsass/src/environment.cpp +1 -1
- data/ext/libsass/src/eval.cpp +42 -14
- data/ext/libsass/src/eval.hpp +1 -1
- data/ext/libsass/src/expand.cpp +24 -8
- data/ext/libsass/src/expand.hpp +2 -1
- data/ext/libsass/src/extend.cpp +55 -15
- data/ext/libsass/src/extend.hpp +5 -1
- data/ext/libsass/src/functions.cpp +10 -5
- data/ext/libsass/src/inspect.cpp +25 -19
- data/ext/libsass/src/inspect.hpp +2 -2
- data/ext/libsass/src/json.cpp +20 -9
- data/ext/libsass/src/json.hpp +5 -5
- data/ext/libsass/src/lexer.cpp +4 -1
- data/ext/libsass/src/lexer.hpp +21 -0
- data/ext/libsass/src/listize.cpp +2 -1
- data/ext/libsass/src/operation.hpp +4 -4
- data/ext/libsass/src/output.cpp +1 -1
- data/ext/libsass/src/output.hpp +1 -1
- data/ext/libsass/src/parser.cpp +189 -90
- data/ext/libsass/src/parser.hpp +42 -2
- data/ext/libsass/src/prelexer.cpp +474 -7
- data/ext/libsass/src/prelexer.hpp +15 -2
- data/ext/libsass/src/remove_placeholders.cpp +5 -5
- data/ext/libsass/src/remove_placeholders.hpp +3 -2
- data/ext/libsass/src/sass.cpp +33 -3
- data/ext/libsass/src/sass2scss.cpp +7 -0
- data/ext/libsass/src/sass_context.cpp +32 -62
- data/ext/libsass/src/sass_functions.cpp +3 -3
- data/ext/libsass/src/sass_values.cpp +5 -5
- data/ext/libsass/src/utf8/unchecked.h +16 -16
- data/ext/libsass/src/util.cpp +51 -30
- data/ext/libsass/src/util.hpp +6 -1
- data/ext/libsass/win/libsass.targets +0 -2
- data/ext/libsass/win/libsass.vcxproj.filters +0 -6
- data/lib/sassc/engine.rb +4 -1
- data/lib/sassc/error.rb +23 -1
- data/lib/sassc/version.rb +1 -1
- data/test/error_test.rb +27 -0
- data/test/native_test.rb +1 -1
- metadata +5 -5
- data/ext/libsass/include/sass/interface.h +0 -105
- data/ext/libsass/src/sass_interface.cpp +0 -215
data/ext/libsass/src/cssize.hpp
CHANGED
@@ -16,6 +16,7 @@ namespace Sass {
|
|
16
16
|
Context& ctx;
|
17
17
|
std::vector<Block*> block_stack;
|
18
18
|
std::vector<Statement*> p_stack;
|
19
|
+
std::vector<Selector_List*> s_stack;
|
19
20
|
Backtrace* backtrace;
|
20
21
|
|
21
22
|
Statement* fallback_impl(AST_Node* n);
|
@@ -24,6 +25,8 @@ namespace Sass {
|
|
24
25
|
Cssize(Context&, Backtrace*);
|
25
26
|
~Cssize() { }
|
26
27
|
|
28
|
+
Selector_List* selector();
|
29
|
+
|
27
30
|
Statement* operator()(Block*);
|
28
31
|
Statement* operator()(Ruleset*);
|
29
32
|
// Statement* operator()(Propset*);
|
@@ -31,7 +34,7 @@ namespace Sass {
|
|
31
34
|
Statement* operator()(Media_Block*);
|
32
35
|
Statement* operator()(Supports_Block*);
|
33
36
|
Statement* operator()(At_Root_Block*);
|
34
|
-
Statement* operator()(
|
37
|
+
Statement* operator()(Directive*);
|
35
38
|
Statement* operator()(Keyframe_Rule*);
|
36
39
|
// Statement* operator()(Declaration*);
|
37
40
|
// Statement* operator()(Assignment*);
|
@@ -53,7 +56,7 @@ namespace Sass {
|
|
53
56
|
|
54
57
|
Statement* parent();
|
55
58
|
std::vector<std::pair<bool, Block*>> slice_by_bubble(Statement*);
|
56
|
-
Statement* bubble(
|
59
|
+
Statement* bubble(Directive*);
|
57
60
|
Statement* bubble(At_Root_Block*);
|
58
61
|
Statement* bubble(Media_Block*);
|
59
62
|
Statement* bubble(Supports_Block*);
|
@@ -352,6 +352,7 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
|
|
352
352
|
Content* block = dynamic_cast<Content*>(node);
|
353
353
|
std::cerr << ind << "Content " << block;
|
354
354
|
std::cerr << " (" << pstate_source_position(node) << ")";
|
355
|
+
std::cerr << " [@media:" << block->media_block() << "]";
|
355
356
|
std::cerr << " " << block->tabs() << std::endl;
|
356
357
|
} else if (dynamic_cast<Import_Stub*>(node)) {
|
357
358
|
Import_Stub* block = dynamic_cast<Import_Stub*>(node);
|
@@ -387,9 +388,9 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
|
|
387
388
|
std::cerr << " " << has_block->tabs() << std::endl;
|
388
389
|
if (has_block->selector()) debug_ast(has_block->selector(), ind + "@");
|
389
390
|
if (has_block->block()) for(auto i : has_block->block()->elements()) { debug_ast(i, ind + " ", env); }
|
390
|
-
} else if (dynamic_cast<
|
391
|
-
|
392
|
-
std::cerr << ind << "
|
391
|
+
} else if (dynamic_cast<Directive*>(node)) {
|
392
|
+
Directive* block = dynamic_cast<Directive*>(node);
|
393
|
+
std::cerr << ind << "Directive " << block;
|
393
394
|
std::cerr << " (" << pstate_source_position(node) << ")";
|
394
395
|
std::cerr << " [" << block->keyword() << "] " << block->tabs() << std::endl;
|
395
396
|
debug_ast(block->selector(), ind + "~", env);
|
@@ -556,6 +557,7 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
|
|
556
557
|
(expression->separator() == SASS_COMMA ? "Comma " : expression->separator() == SASS_HASH ? "Map" : "Space ") <<
|
557
558
|
" [delayed: " << expression->is_delayed() << "] " <<
|
558
559
|
" [interpolant: " << expression->is_interpolant() << "] " <<
|
560
|
+
" [listized: " << expression->from_selector() << "] " <<
|
559
561
|
" [arglist: " << expression->is_arglist() << "] " <<
|
560
562
|
" [hash: " << expression->hash() << "] " <<
|
561
563
|
std::endl;
|
@@ -564,6 +566,7 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
|
|
564
566
|
Content* expression = dynamic_cast<Content*>(node);
|
565
567
|
std::cerr << ind << "Content " << expression;
|
566
568
|
std::cerr << " (" << pstate_source_position(node) << ")";
|
569
|
+
std::cerr << " [@media:" << expression->media_block() << "]";
|
567
570
|
std::cerr << " [Statement]" << std::endl;
|
568
571
|
} else if (dynamic_cast<Boolean*>(node)) {
|
569
572
|
Boolean* expression = dynamic_cast<Boolean*>(node);
|
data/ext/libsass/src/emitter.cpp
CHANGED
@@ -204,7 +204,7 @@ namespace Sass {
|
|
204
204
|
void Emitter::append_optional_space()
|
205
205
|
{
|
206
206
|
if ((output_style() != COMPRESSED) && buffer().size()) {
|
207
|
-
char lst = buffer().at(buffer().length() - 1);
|
207
|
+
unsigned char lst = buffer().at(buffer().length() - 1);
|
208
208
|
if (!isspace(lst) || scheduled_delimiter) {
|
209
209
|
append_mandatory_space();
|
210
210
|
}
|
@@ -180,7 +180,7 @@ namespace Sass {
|
|
180
180
|
if (!ends_with(i->first, "[f]") && !ends_with(i->first, "[f]4") && !ends_with(i->first, "[f]2")) {
|
181
181
|
std::cerr << prefix << std::string(indent, ' ') << i->first << " " << i->second;
|
182
182
|
if (Value* val = dynamic_cast<Value*>(i->second))
|
183
|
-
{ std::cerr << " : " << val->to_string(
|
183
|
+
{ std::cerr << " : " << val->to_string(); }
|
184
184
|
std::cerr << std::endl;
|
185
185
|
}
|
186
186
|
}
|
data/ext/libsass/src/eval.cpp
CHANGED
@@ -458,6 +458,7 @@ namespace Sass {
|
|
458
458
|
*ll << (*l)[i]->perform(this);
|
459
459
|
}
|
460
460
|
ll->is_interpolant(l->is_interpolant());
|
461
|
+
ll->from_selector(l->from_selector());
|
461
462
|
ll->is_expanded(true);
|
462
463
|
return ll;
|
463
464
|
}
|
@@ -834,15 +835,31 @@ namespace Sass {
|
|
834
835
|
}
|
835
836
|
std::string name(Util::normalize_underscores(c->name()));
|
836
837
|
std::string full_name(name + "[f]");
|
837
|
-
Arguments* args = c->arguments();
|
838
|
-
|
839
|
-
|
838
|
+
Arguments* args = SASS_MEMORY_NEW(ctx.mem, Arguments, *c->arguments());
|
839
|
+
|
840
|
+
// handle call here if valid arg
|
841
|
+
// otherwise we eval arguments to early
|
842
|
+
if (name == "call" && args->length() > 0) {
|
843
|
+
Expression* redirect = args->at(0)->perform(this);
|
844
|
+
args->erase(args->begin());
|
845
|
+
Function_Call* lit = SASS_MEMORY_NEW(ctx.mem, Function_Call,
|
846
|
+
c->pstate(),
|
847
|
+
unquote(redirect->to_string()),
|
848
|
+
args);
|
849
|
+
return operator()(lit);
|
840
850
|
}
|
841
851
|
|
842
852
|
Env* env = environment();
|
843
853
|
if (!env->has(full_name)) {
|
844
854
|
if (!env->has("*[f]")) {
|
845
855
|
// just pass it through as a literal
|
856
|
+
for (Argument* arg : *args) {
|
857
|
+
if (Binary_Expression* b = dynamic_cast<Binary_Expression*>(arg->value())) {
|
858
|
+
b->reset_whitespace();
|
859
|
+
arg->is_delayed(b->can_delay()); // delay
|
860
|
+
}
|
861
|
+
}
|
862
|
+
args = static_cast<Arguments*>(args->perform(this));
|
846
863
|
Function_Call* lit = SASS_MEMORY_NEW(ctx.mem, Function_Call,
|
847
864
|
c->pstate(),
|
848
865
|
c->name(),
|
@@ -861,6 +878,10 @@ namespace Sass {
|
|
861
878
|
}
|
862
879
|
}
|
863
880
|
|
881
|
+
if (full_name != "if[f]") {
|
882
|
+
args = static_cast<Arguments*>(args->perform(this));
|
883
|
+
}
|
884
|
+
|
864
885
|
Definition* def = static_cast<Definition*>((*env)[full_name]);
|
865
886
|
|
866
887
|
if (def->is_overload_stub()) {
|
@@ -1087,7 +1108,7 @@ namespace Sass {
|
|
1087
1108
|
void Eval::interpolation(Context& ctx, std::string& res, Expression* ex, bool into_quotes, bool was_itpl) {
|
1088
1109
|
|
1089
1110
|
bool needs_closing_brace = false;
|
1090
|
-
|
1111
|
+
|
1091
1112
|
if (Arguments* args = dynamic_cast<Arguments*>(ex)) {
|
1092
1113
|
List* ll = SASS_MEMORY_NEW(ctx.mem, List, args->pstate(), 0, SASS_COMMA);
|
1093
1114
|
for(auto arg : *args) {
|
@@ -1165,8 +1186,10 @@ namespace Sass {
|
|
1165
1186
|
if (!dynamic_cast<String_Quoted*>((*s)[0]) && !dynamic_cast<String_Quoted*>((*s)[L - 1])) {
|
1166
1187
|
if (String_Constant* l = dynamic_cast<String_Constant*>((*s)[0])) {
|
1167
1188
|
if (String_Constant* r = dynamic_cast<String_Constant*>((*s)[L - 1])) {
|
1168
|
-
if (
|
1169
|
-
|
1189
|
+
if (r->value().size() > 0) {
|
1190
|
+
if (l->value()[0] == '"' && r->value()[r->value().size() - 1] == '"') into_quotes = true;
|
1191
|
+
if (l->value()[0] == '\'' && r->value()[r->value().size() - 1] == '\'') into_quotes = true;
|
1192
|
+
}
|
1170
1193
|
}
|
1171
1194
|
}
|
1172
1195
|
}
|
@@ -1176,7 +1199,6 @@ namespace Sass {
|
|
1176
1199
|
std::string res("");
|
1177
1200
|
for (size_t i = 0; i < L; ++i) {
|
1178
1201
|
bool is_quoted = dynamic_cast<String_Quoted*>((*s)[i]) != NULL;
|
1179
|
-
(*s)[i]->perform(this);
|
1180
1202
|
if (was_quoted && !(*s)[i]->is_interpolant() && !was_interpolant) { res += " "; }
|
1181
1203
|
else if (i > 0 && is_quoted && !(*s)[i]->is_interpolant() && !was_interpolant) { res += " "; }
|
1182
1204
|
Expression* ex = (*s)[i]->is_delayed() ? (*s)[i] : (*s)[i]->perform(this);
|
@@ -1260,17 +1282,16 @@ namespace Sass {
|
|
1260
1282
|
return cc;
|
1261
1283
|
}
|
1262
1284
|
|
1263
|
-
Expression* Eval::operator()(
|
1285
|
+
Expression* Eval::operator()(At_Root_Query* e)
|
1264
1286
|
{
|
1265
1287
|
Expression* feature = e->feature();
|
1266
1288
|
feature = (feature ? feature->perform(this) : 0);
|
1267
1289
|
Expression* value = e->value();
|
1268
1290
|
value = (value ? value->perform(this) : 0);
|
1269
|
-
Expression* ee = SASS_MEMORY_NEW(ctx.mem,
|
1291
|
+
Expression* ee = SASS_MEMORY_NEW(ctx.mem, At_Root_Query,
|
1270
1292
|
e->pstate(),
|
1271
1293
|
static_cast<String*>(feature),
|
1272
|
-
value
|
1273
|
-
e->is_interpolated());
|
1294
|
+
value);
|
1274
1295
|
return ee;
|
1275
1296
|
}
|
1276
1297
|
|
@@ -1322,7 +1343,8 @@ namespace Sass {
|
|
1322
1343
|
Expression* Eval::operator()(Argument* a)
|
1323
1344
|
{
|
1324
1345
|
Expression* val = a->value();
|
1325
|
-
|
1346
|
+
// delay missin function arguments?
|
1347
|
+
val->is_delayed(a->is_delayed());
|
1326
1348
|
val = val->perform(this);
|
1327
1349
|
val->is_delayed(false);
|
1328
1350
|
|
@@ -1355,6 +1377,7 @@ namespace Sass {
|
|
1355
1377
|
Expression* Eval::operator()(Arguments* a)
|
1356
1378
|
{
|
1357
1379
|
Arguments* aa = SASS_MEMORY_NEW(ctx.mem, Arguments, a->pstate());
|
1380
|
+
if (a->length() == 0) return aa;
|
1358
1381
|
for (size_t i = 0, L = a->length(); i < L; ++i) {
|
1359
1382
|
Argument* arg = static_cast<Argument*>((*a)[i]->perform(this));
|
1360
1383
|
if (!(arg->is_rest_argument() || arg->is_keyword_argument())) {
|
@@ -1660,7 +1683,9 @@ namespace Sass {
|
|
1660
1683
|
{
|
1661
1684
|
std::vector<Selector_List*> rv;
|
1662
1685
|
Selector_List* sl = SASS_MEMORY_NEW(ctx.mem, Selector_List, s->pstate());
|
1686
|
+
sl->is_optional(s->is_optional());
|
1663
1687
|
sl->media_block(s->media_block());
|
1688
|
+
sl->is_optional(s->is_optional());
|
1664
1689
|
for (size_t i = 0, iL = s->length(); i < iL; ++i) {
|
1665
1690
|
rv.push_back(operator()((*s)[i]));
|
1666
1691
|
}
|
@@ -1707,9 +1732,12 @@ namespace Sass {
|
|
1707
1732
|
{
|
1708
1733
|
// the parser will look for a brace to end the selector
|
1709
1734
|
std::string result_str(s->contents()->perform(this)->to_string(ctx.c_options));
|
1710
|
-
result_str = unquote(Util::rtrim(result_str)) + "{";
|
1735
|
+
result_str = unquote(Util::rtrim(result_str)) + "\n{";
|
1711
1736
|
Parser p = Parser::from_c_str(result_str.c_str(), ctx, s->pstate());
|
1712
|
-
|
1737
|
+
p.last_media_block = s->media_block();
|
1738
|
+
Selector_List* sl = p.parse_selector_list(exp.block_stack.back()->is_root());
|
1739
|
+
if (s->has_parent_ref()) sl->remove_parent_selectors();
|
1740
|
+
return operator()(sl);
|
1713
1741
|
}
|
1714
1742
|
|
1715
1743
|
Expression* Eval::operator()(Parent_Selector* p)
|
data/ext/libsass/src/eval.hpp
CHANGED
@@ -57,7 +57,7 @@ namespace Sass {
|
|
57
57
|
// Expression* operator()(Selector_List*);
|
58
58
|
Expression* operator()(Media_Query*);
|
59
59
|
Expression* operator()(Media_Query_Expression*);
|
60
|
-
Expression* operator()(
|
60
|
+
Expression* operator()(At_Root_Query*);
|
61
61
|
Expression* operator()(Supports_Operator*);
|
62
62
|
Expression* operator()(Supports_Negation*);
|
63
63
|
Expression* operator()(Supports_Declaration*);
|
data/ext/libsass/src/expand.cpp
CHANGED
@@ -19,6 +19,7 @@ namespace Sass {
|
|
19
19
|
call_stack(std::vector<AST_Node*>()),
|
20
20
|
property_stack(std::vector<String*>()),
|
21
21
|
selector_stack(std::vector<Selector_List*>()),
|
22
|
+
media_block_stack(std::vector<Media_Block*>()),
|
22
23
|
backtrace_stack(std::vector<Backtrace*>()),
|
23
24
|
in_keyframes(false)
|
24
25
|
{
|
@@ -29,6 +30,7 @@ namespace Sass {
|
|
29
30
|
// import_stack.push_back(0);
|
30
31
|
property_stack.push_back(0);
|
31
32
|
selector_stack.push_back(0);
|
33
|
+
media_block_stack.push_back(0);
|
32
34
|
backtrace_stack.push_back(0);
|
33
35
|
backtrace_stack.push_back(bt);
|
34
36
|
}
|
@@ -134,6 +136,7 @@ namespace Sass {
|
|
134
136
|
env = new Env(environment());
|
135
137
|
env_stack.push_back(env);
|
136
138
|
}
|
139
|
+
sel->set_media_block(media_block_stack.back());
|
137
140
|
Block* blk = r->block()->perform(this)->block();
|
138
141
|
Ruleset* rr = SASS_MEMORY_NEW(ctx.mem, Ruleset,
|
139
142
|
r->pstate(),
|
@@ -144,6 +147,7 @@ namespace Sass {
|
|
144
147
|
env_stack.pop_back();
|
145
148
|
delete env;
|
146
149
|
}
|
150
|
+
rr->is_root(r->is_root());
|
147
151
|
rr->tabs(r->tabs());
|
148
152
|
|
149
153
|
return rr;
|
@@ -195,9 +199,10 @@ namespace Sass {
|
|
195
199
|
|
196
200
|
Statement* Expand::operator()(Media_Block* m)
|
197
201
|
{
|
202
|
+
media_block_stack.push_back(m);
|
198
203
|
Expression* mq = m->media_queries()->perform(&eval);
|
199
204
|
std::string str_mq(mq->to_string(ctx.c_options));
|
200
|
-
char* str =
|
205
|
+
char* str = sass_copy_c_string(str_mq.c_str());
|
201
206
|
ctx.strings.push_back(str);
|
202
207
|
Parser p(Parser::from_c_str(str, ctx, mq->pstate()));
|
203
208
|
mq = p.parse_media_queries();
|
@@ -206,6 +211,7 @@ namespace Sass {
|
|
206
211
|
static_cast<List*>(mq->perform(&eval)),
|
207
212
|
m->block()->perform(this)->block(),
|
208
213
|
0);
|
214
|
+
media_block_stack.pop_back();
|
209
215
|
mm->tabs(m->tabs());
|
210
216
|
return mm;
|
211
217
|
}
|
@@ -216,17 +222,17 @@ namespace Sass {
|
|
216
222
|
// if (ab) ab->is_root(true);
|
217
223
|
Expression* ae = a->expression();
|
218
224
|
if (ae) ae = ae->perform(&eval);
|
219
|
-
else ae = SASS_MEMORY_NEW(ctx.mem,
|
225
|
+
else ae = SASS_MEMORY_NEW(ctx.mem, At_Root_Query, a->pstate());
|
220
226
|
Block* bb = ab ? ab->perform(this)->block() : 0;
|
221
227
|
At_Root_Block* aa = SASS_MEMORY_NEW(ctx.mem, At_Root_Block,
|
222
228
|
a->pstate(),
|
223
229
|
bb,
|
224
|
-
static_cast<
|
230
|
+
static_cast<At_Root_Query*>(ae));
|
225
231
|
// aa->block()->is_root(true);
|
226
232
|
return aa;
|
227
233
|
}
|
228
234
|
|
229
|
-
Statement* Expand::operator()(
|
235
|
+
Statement* Expand::operator()(Directive* a)
|
230
236
|
{
|
231
237
|
LOCAL_FLAG(in_keyframes, a->is_keyframes());
|
232
238
|
Block* ab = a->block();
|
@@ -237,7 +243,7 @@ namespace Sass {
|
|
237
243
|
if (as) as = dynamic_cast<Selector*>(as->perform(&eval));
|
238
244
|
selector_stack.pop_back();
|
239
245
|
Block* bb = ab ? ab->perform(this)->block() : 0;
|
240
|
-
|
246
|
+
Directive* aa = SASS_MEMORY_NEW(ctx.mem, Directive,
|
241
247
|
a->pstate(),
|
242
248
|
a->keyword(),
|
243
249
|
as,
|
@@ -593,7 +599,7 @@ namespace Sass {
|
|
593
599
|
error("Can't extend " + sel_str + ": can't extend nested selectors", c->pstate(), backtrace());
|
594
600
|
}
|
595
601
|
Compound_Selector* placeholder = c->head();
|
596
|
-
|
602
|
+
if (contextualized->is_optional()) placeholder->is_optional(true);
|
597
603
|
for (size_t i = 0, L = extender->length(); i < L; ++i) {
|
598
604
|
Complex_Selector* sel = (*extender)[i];
|
599
605
|
if (!(sel->head() && sel->head()->length() > 0 &&
|
@@ -621,8 +627,18 @@ namespace Sass {
|
|
621
627
|
Statement* Expand::operator()(Extension* e)
|
622
628
|
{
|
623
629
|
if (Selector_List* extender = dynamic_cast<Selector_List*>(selector())) {
|
624
|
-
selector_stack.push_back(0);
|
625
630
|
Selector* s = e->selector();
|
631
|
+
if (Selector_Schema* schema = dynamic_cast<Selector_Schema*>(s)) {
|
632
|
+
if (schema->has_parent_ref()) s = eval(schema);
|
633
|
+
}
|
634
|
+
if (Selector_List* sl = dynamic_cast<Selector_List*>(s)) {
|
635
|
+
for (Complex_Selector* cs : *sl) {
|
636
|
+
if (cs != NULL && cs->head() != NULL) {
|
637
|
+
cs->head()->media_block(media_block_stack.back());
|
638
|
+
}
|
639
|
+
}
|
640
|
+
}
|
641
|
+
selector_stack.push_back(0);
|
626
642
|
expand_selector_list(s, extender);
|
627
643
|
selector_stack.pop_back();
|
628
644
|
}
|
@@ -637,7 +653,7 @@ namespace Sass {
|
|
637
653
|
(d->type() == Definition::MIXIN ? "[m]" : "[f]")] = dd;
|
638
654
|
|
639
655
|
if (d->type() == Definition::FUNCTION && (
|
640
|
-
d->name()
|
656
|
+
Prelexer::calc_fn_call(d->name().c_str()) ||
|
641
657
|
d->name() == "element" ||
|
642
658
|
d->name() == "expression" ||
|
643
659
|
d->name() == "url"
|
data/ext/libsass/src/expand.hpp
CHANGED
@@ -33,6 +33,7 @@ namespace Sass {
|
|
33
33
|
std::vector<AST_Node*> call_stack;
|
34
34
|
std::vector<String*> property_stack;
|
35
35
|
std::vector<Selector_List*> selector_stack;
|
36
|
+
std::vector<Media_Block*> media_block_stack;
|
36
37
|
std::vector<Backtrace*>backtrace_stack;
|
37
38
|
bool in_keyframes;
|
38
39
|
|
@@ -51,7 +52,7 @@ namespace Sass {
|
|
51
52
|
Statement* operator()(Media_Block*);
|
52
53
|
Statement* operator()(Supports_Block*);
|
53
54
|
Statement* operator()(At_Root_Block*);
|
54
|
-
Statement* operator()(
|
55
|
+
Statement* operator()(Directive*);
|
55
56
|
Statement* operator()(Declaration*);
|
56
57
|
Statement* operator()(Assignment*);
|
57
58
|
Statement* operator()(Import*);
|
data/ext/libsass/src/extend.cpp
CHANGED
@@ -6,6 +6,7 @@
|
|
6
6
|
#include "parser.hpp"
|
7
7
|
#include "node.hpp"
|
8
8
|
#include "sass_util.hpp"
|
9
|
+
#include "remove_placeholders.hpp"
|
9
10
|
#include "debug.hpp"
|
10
11
|
#include <iostream>
|
11
12
|
#include <deque>
|
@@ -1463,6 +1464,7 @@ namespace Sass {
|
|
1463
1464
|
Node current = afters.collection()->front().clone(ctx);
|
1464
1465
|
afters.collection()->pop_front();
|
1465
1466
|
DEBUG_PRINTLN(WEAVE, "CURRENT: " << current)
|
1467
|
+
if (current.collection()->size() == 0) continue;
|
1466
1468
|
|
1467
1469
|
Node last_current = Node::createCollection();
|
1468
1470
|
last_current.collection()->push_back(current.collection()->back());
|
@@ -1737,14 +1739,14 @@ namespace Sass {
|
|
1737
1739
|
SubsetMapEntries entries = subset_map.get_v(pHead->to_str_vec());
|
1738
1740
|
for (ExtensionPair ext : entries) {
|
1739
1741
|
// check if both selectors have the same media block parent
|
1740
|
-
if (ext.first->media_block() == pComplexSelector->media_block()) continue;
|
1742
|
+
// if (ext.first->media_block() == pComplexSelector->media_block()) continue;
|
1741
1743
|
if (ext.second->media_block() == 0) continue;
|
1742
|
-
if (
|
1744
|
+
if (pHead->media_block() &&
|
1743
1745
|
ext.second->media_block()->media_queries() &&
|
1744
|
-
|
1746
|
+
pHead->media_block()->media_queries()
|
1745
1747
|
) {
|
1746
1748
|
std::string query_left(ext.second->media_block()->media_queries()->to_string(ctx.c_options));
|
1747
|
-
std::string query_right(
|
1749
|
+
std::string query_right(pHead->media_block()->media_queries()->to_string(ctx.c_options));
|
1748
1750
|
if (query_left == query_right) continue;
|
1749
1751
|
}
|
1750
1752
|
|
@@ -1943,19 +1945,57 @@ namespace Sass {
|
|
1943
1945
|
}
|
1944
1946
|
}
|
1945
1947
|
|
1946
|
-
|
1947
|
-
|
1948
|
-
|
1949
|
-
|
1950
|
-
|
1951
|
-
|
1952
|
-
|
1953
|
-
|
1948
|
+
Remove_Placeholders remove_placeholders(ctx);
|
1949
|
+
// it seems that we have to remove the place holders early here
|
1950
|
+
// normally we do this as the very last step (compare to ruby sass)
|
1951
|
+
pNewSelectors = remove_placeholders.remove_placeholders(pNewSelectors);
|
1952
|
+
|
1953
|
+
// unwrap all wrapped selectors with inner lists
|
1954
|
+
for (Complex_Selector* cur : *pNewSelectors) {
|
1955
|
+
// process tails
|
1956
|
+
while (cur) {
|
1957
|
+
// process header
|
1958
|
+
if (cur->head()) {
|
1959
|
+
// create a copy since we add multiple items if stuff get unwrapped
|
1960
|
+
Compound_Selector* cpy_head = SASS_MEMORY_NEW(ctx.mem, Compound_Selector, cur->pstate());
|
1961
|
+
for (Simple_Selector* hs : *cur->head()) {
|
1962
|
+
if (Wrapped_Selector* ws = dynamic_cast<Wrapped_Selector*>(hs)) {
|
1963
|
+
if (Selector_List* sl = dynamic_cast<Selector_List*>(ws->selector())) {
|
1964
|
+
// special case for ruby ass
|
1965
|
+
if (sl->empty()) {
|
1966
|
+
// this seems inconsistent but it is how ruby sass seems to remove parentheses
|
1967
|
+
*cpy_head << SASS_MEMORY_NEW(ctx.mem, Type_Selector, hs->pstate(), ws->name());
|
1968
|
+
}
|
1969
|
+
// has wrapped selectors
|
1970
|
+
else {
|
1971
|
+
// extend the inner list of wrapped selector
|
1972
|
+
Selector_List* ext_sl = extendSelectorList(sl, ctx, subset_map);
|
1973
|
+
for (size_t i = 0; i < ext_sl->length(); i += 1) {
|
1974
|
+
if (Complex_Selector* ext_cs = ext_sl->at(i)) {
|
1975
|
+
// create clones for wrapped selector and the inner list
|
1976
|
+
Wrapped_Selector* cpy_ws = SASS_MEMORY_NEW(ctx.mem, Wrapped_Selector, *ws);
|
1977
|
+
Selector_List* cpy_ws_sl = SASS_MEMORY_NEW(ctx.mem, Selector_List, sl->pstate());
|
1978
|
+
// remove parent selectors from inner selector
|
1979
|
+
if (ext_cs->first()) *cpy_ws_sl << ext_cs->first();
|
1980
|
+
// assign list to clone
|
1981
|
+
cpy_ws->selector(cpy_ws_sl);
|
1982
|
+
// append the clone
|
1983
|
+
*cpy_head << cpy_ws;
|
1984
|
+
}
|
1985
|
+
}
|
1986
|
+
}
|
1987
|
+
} else {
|
1988
|
+
*cpy_head << hs;
|
1989
|
+
}
|
1990
|
+
} else {
|
1991
|
+
*cpy_head << hs;
|
1954
1992
|
}
|
1955
1993
|
}
|
1994
|
+
// replace header
|
1995
|
+
cur->head(cpy_head);
|
1956
1996
|
}
|
1957
|
-
|
1958
|
-
|
1997
|
+
// process tail
|
1998
|
+
cur = cur->tail();
|
1959
1999
|
}
|
1960
2000
|
}
|
1961
2001
|
return pNewSelectors;
|
@@ -2068,7 +2108,7 @@ namespace Sass {
|
|
2068
2108
|
pMediaBlock->block()->perform(this);
|
2069
2109
|
}
|
2070
2110
|
|
2071
|
-
void Extend::operator()(
|
2111
|
+
void Extend::operator()(Directive* a)
|
2072
2112
|
{
|
2073
2113
|
// Selector_List* ls = dynamic_cast<Selector_List*>(a->selector());
|
2074
2114
|
// selector_stack.push_back(ls);
|