sassc 1.9.0 → 1.10.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/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);
|