sassc 1.8.3 → 1.8.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -1
- data/ext/libsass/.editorconfig +1 -1
- data/ext/libsass/.gitignore +1 -0
- data/ext/libsass/LICENSE +1 -1
- data/ext/libsass/Makefile +20 -14
- data/ext/libsass/Makefile.conf +0 -1
- data/ext/libsass/Readme.md +3 -1
- data/ext/libsass/appveyor.yml +19 -11
- data/ext/libsass/docs/api-importer-example.md +2 -1235
- data/ext/libsass/docs/build-with-autotools.md +10 -0
- data/ext/libsass/docs/build-with-makefiles.md +18 -0
- data/ext/libsass/include/sass/base.h +4 -1
- data/ext/libsass/include/sass/values.h +2 -1
- data/ext/libsass/src/ast.cpp +279 -346
- data/ext/libsass/src/ast.hpp +234 -60
- data/ext/libsass/src/base64vlq.cpp +1 -0
- data/ext/libsass/src/bind.cpp +35 -45
- data/ext/libsass/src/bind.hpp +1 -0
- data/ext/libsass/src/color_maps.cpp +1 -0
- data/ext/libsass/src/constants.cpp +4 -1
- data/ext/libsass/src/constants.hpp +2 -1
- data/ext/libsass/src/context.cpp +41 -31
- data/ext/libsass/src/context.hpp +10 -10
- data/ext/libsass/src/cssize.cpp +7 -4
- data/ext/libsass/src/cssize.hpp +1 -3
- data/ext/libsass/src/debugger.hpp +73 -14
- data/ext/libsass/src/emitter.cpp +37 -25
- data/ext/libsass/src/emitter.hpp +10 -9
- data/ext/libsass/src/environment.cpp +16 -5
- data/ext/libsass/src/environment.hpp +5 -3
- data/ext/libsass/src/error_handling.cpp +91 -14
- data/ext/libsass/src/error_handling.hpp +105 -4
- data/ext/libsass/src/eval.cpp +519 -330
- data/ext/libsass/src/eval.hpp +12 -13
- data/ext/libsass/src/expand.cpp +92 -56
- data/ext/libsass/src/expand.hpp +5 -3
- data/ext/libsass/src/extend.cpp +60 -51
- data/ext/libsass/src/extend.hpp +1 -3
- data/ext/libsass/src/file.cpp +37 -27
- data/ext/libsass/src/functions.cpp +78 -62
- data/ext/libsass/src/functions.hpp +1 -0
- data/ext/libsass/src/inspect.cpp +293 -64
- data/ext/libsass/src/inspect.hpp +2 -0
- data/ext/libsass/src/lexer.cpp +1 -0
- data/ext/libsass/src/listize.cpp +14 -15
- data/ext/libsass/src/listize.hpp +3 -5
- data/ext/libsass/src/memory_manager.cpp +1 -0
- data/ext/libsass/src/node.cpp +2 -3
- data/ext/libsass/src/operation.hpp +70 -71
- data/ext/libsass/src/output.cpp +28 -32
- data/ext/libsass/src/output.hpp +1 -2
- data/ext/libsass/src/parser.cpp +402 -183
- data/ext/libsass/src/parser.hpp +19 -9
- data/ext/libsass/src/plugins.cpp +1 -0
- data/ext/libsass/src/position.cpp +1 -0
- data/ext/libsass/src/prelexer.cpp +134 -56
- data/ext/libsass/src/prelexer.hpp +51 -3
- data/ext/libsass/src/remove_placeholders.cpp +35 -9
- data/ext/libsass/src/remove_placeholders.hpp +4 -3
- data/ext/libsass/src/sass.cpp +1 -0
- data/ext/libsass/src/sass.hpp +129 -0
- data/ext/libsass/src/sass_context.cpp +31 -14
- data/ext/libsass/src/sass_context.hpp +2 -31
- data/ext/libsass/src/sass_functions.cpp +1 -0
- data/ext/libsass/src/sass_interface.cpp +5 -6
- data/ext/libsass/src/sass_util.cpp +1 -2
- data/ext/libsass/src/sass_util.hpp +5 -5
- data/ext/libsass/src/sass_values.cpp +13 -10
- data/ext/libsass/src/source_map.cpp +4 -3
- data/ext/libsass/src/source_map.hpp +2 -2
- data/ext/libsass/src/subset_map.hpp +0 -1
- data/ext/libsass/src/to_c.cpp +1 -0
- data/ext/libsass/src/to_c.hpp +1 -3
- data/ext/libsass/src/to_value.cpp +3 -5
- data/ext/libsass/src/to_value.hpp +1 -1
- data/ext/libsass/src/units.cpp +96 -59
- data/ext/libsass/src/units.hpp +10 -8
- data/ext/libsass/src/utf8_string.cpp +5 -0
- data/ext/libsass/src/util.cpp +23 -156
- data/ext/libsass/src/util.hpp +10 -14
- data/ext/libsass/src/values.cpp +1 -0
- data/ext/libsass/test/test_node.cpp +2 -6
- data/ext/libsass/test/test_selector_difference.cpp +1 -3
- data/ext/libsass/test/test_specificity.cpp +0 -2
- data/ext/libsass/test/test_superselector.cpp +0 -2
- data/ext/libsass/test/test_unification.cpp +1 -3
- data/ext/libsass/win/libsass.targets +18 -5
- data/ext/libsass/win/libsass.vcxproj +9 -7
- data/ext/libsass/win/libsass.vcxproj.filters +148 -106
- data/lib/sassc/version.rb +1 -1
- data/test/engine_test.rb +12 -0
- data/test/native_test.rb +1 -1
- metadata +3 -4
- data/ext/libsass/src/to_string.cpp +0 -48
- data/ext/libsass/src/to_string.hpp +0 -38
data/ext/libsass/src/eval.hpp
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
#ifndef SASS_EVAL_H
|
2
2
|
#define SASS_EVAL_H
|
3
3
|
|
4
|
+
#include "ast.hpp"
|
4
5
|
#include "context.hpp"
|
5
|
-
#include "listize.hpp"
|
6
6
|
#include "operation.hpp"
|
7
|
+
#include "environment.hpp"
|
7
8
|
|
8
9
|
namespace Sass {
|
9
10
|
|
10
11
|
class Expand;
|
11
12
|
class Context;
|
12
|
-
class Listize;
|
13
13
|
|
14
14
|
class Eval : public Operation_CRTP<Expression*, Eval> {
|
15
15
|
|
@@ -19,17 +19,16 @@ namespace Sass {
|
|
19
19
|
public:
|
20
20
|
Expand& exp;
|
21
21
|
Context& ctx;
|
22
|
-
Listize listize;
|
23
22
|
Eval(Expand& exp);
|
24
|
-
|
23
|
+
~Eval();
|
24
|
+
|
25
|
+
bool is_in_comment;
|
25
26
|
|
26
27
|
Env* environment();
|
27
28
|
Context& context();
|
28
29
|
Selector_List* selector();
|
29
30
|
Backtrace* backtrace();
|
30
31
|
|
31
|
-
using Operation<Expression*>::operator();
|
32
|
-
|
33
32
|
// for evaluating function bodies
|
34
33
|
Expression* operator()(Block*);
|
35
34
|
Expression* operator()(Assignment*);
|
@@ -87,16 +86,16 @@ namespace Sass {
|
|
87
86
|
|
88
87
|
// -- only need to define two comparisons, and the rest can be implemented in terms of them
|
89
88
|
static bool eq(Expression*, Expression*);
|
90
|
-
static bool lt(Expression*, Expression
|
89
|
+
static bool lt(Expression*, Expression*, std::string op);
|
91
90
|
// -- arithmetic on the combinations that matter
|
92
|
-
static Value* op_numbers(Memory_Manager&, enum Sass_OP, const Number&, const Number&,
|
93
|
-
static Value* op_number_color(Memory_Manager&, enum Sass_OP, const Number&, const Color&,
|
94
|
-
static Value* op_color_number(Memory_Manager&, enum Sass_OP, const Color&, const Number&,
|
95
|
-
static Value* op_colors(Memory_Manager&, enum Sass_OP, const Color&, const Color&,
|
96
|
-
static Value* op_strings(Memory_Manager&,
|
91
|
+
static Value* op_numbers(Memory_Manager&, enum Sass_OP, const Number&, const Number&, struct Sass_Inspect_Options opt, ParserState* pstate = 0);
|
92
|
+
static Value* op_number_color(Memory_Manager&, enum Sass_OP, const Number&, const Color&, struct Sass_Inspect_Options opt, ParserState* pstate = 0);
|
93
|
+
static Value* op_color_number(Memory_Manager&, enum Sass_OP, const Color&, const Number&, struct Sass_Inspect_Options opt, ParserState* pstate = 0);
|
94
|
+
static Value* op_colors(Memory_Manager&, enum Sass_OP, const Color&, const Color&, struct Sass_Inspect_Options opt, ParserState* pstate = 0);
|
95
|
+
static Value* op_strings(Memory_Manager&, Sass::Operand, Value&, Value&, struct Sass_Inspect_Options opt, ParserState* pstate = 0, bool interpolant = false);
|
97
96
|
|
98
97
|
private:
|
99
|
-
std::string
|
98
|
+
void interpolation(Context& ctx, std::string& res, Expression* ex, bool into_quotes, bool was_itpl = false);
|
100
99
|
|
101
100
|
};
|
102
101
|
|
data/ext/libsass/src/expand.cpp
CHANGED
@@ -1,14 +1,10 @@
|
|
1
|
-
#
|
2
|
-
#pragma warning(disable : 4503)
|
3
|
-
#endif
|
4
|
-
|
1
|
+
#include "sass.hpp"
|
5
2
|
#include <iostream>
|
6
3
|
#include <typeinfo>
|
7
4
|
|
8
5
|
#include "expand.hpp"
|
9
6
|
#include "bind.hpp"
|
10
7
|
#include "eval.hpp"
|
11
|
-
#include "to_string.hpp"
|
12
8
|
#include "backtrace.hpp"
|
13
9
|
#include "context.hpp"
|
14
10
|
#include "parser.hpp"
|
@@ -20,6 +16,7 @@ namespace Sass {
|
|
20
16
|
eval(Eval(*this)),
|
21
17
|
env_stack(std::vector<Env*>()),
|
22
18
|
block_stack(std::vector<Block*>()),
|
19
|
+
call_stack(std::vector<AST_Node*>()),
|
23
20
|
property_stack(std::vector<String*>()),
|
24
21
|
selector_stack(std::vector<Selector_List*>()),
|
25
22
|
backtrace_stack(std::vector<Backtrace*>()),
|
@@ -28,6 +25,7 @@ namespace Sass {
|
|
28
25
|
env_stack.push_back(0);
|
29
26
|
env_stack.push_back(env);
|
30
27
|
block_stack.push_back(0);
|
28
|
+
call_stack.push_back(0);
|
31
29
|
// import_stack.push_back(0);
|
32
30
|
property_stack.push_back(0);
|
33
31
|
selector_stack.push_back(0);
|
@@ -106,7 +104,7 @@ namespace Sass {
|
|
106
104
|
while (tail) {
|
107
105
|
if (tail->head()) for (Simple_Selector* header : tail->head()->elements()) {
|
108
106
|
if (dynamic_cast<Parent_Selector*>(header) == NULL) continue; // skip all others
|
109
|
-
|
107
|
+
std::string sel_str(complex_selector->to_string(ctx.c_options));
|
110
108
|
error("Base-level rules cannot contain the parent-selector-referencing character '&'.", header->pstate(), backtrace());
|
111
109
|
}
|
112
110
|
tail = tail->tail();
|
@@ -120,12 +118,21 @@ namespace Sass {
|
|
120
118
|
if (sel == 0) throw std::runtime_error("Expanded null selector");
|
121
119
|
|
122
120
|
selector_stack.push_back(sel);
|
121
|
+
Env* env = 0;
|
122
|
+
if (block_stack.back()->is_root()) {
|
123
|
+
env = new Env(environment());
|
124
|
+
env_stack.push_back(env);
|
125
|
+
}
|
123
126
|
Block* blk = r->block()->perform(this)->block();
|
124
127
|
Ruleset* rr = SASS_MEMORY_NEW(ctx.mem, Ruleset,
|
125
128
|
r->pstate(),
|
126
129
|
sel,
|
127
130
|
blk);
|
128
131
|
selector_stack.pop_back();
|
132
|
+
if (block_stack.back()->is_root()) {
|
133
|
+
env_stack.pop_back();
|
134
|
+
delete env;
|
135
|
+
}
|
129
136
|
rr->tabs(r->tabs());
|
130
137
|
|
131
138
|
return rr;
|
@@ -177,12 +184,15 @@ namespace Sass {
|
|
177
184
|
|
178
185
|
Statement* Expand::operator()(Media_Block* m)
|
179
186
|
{
|
180
|
-
To_String to_string(&ctx);
|
181
187
|
Expression* mq = m->media_queries()->perform(&eval);
|
182
|
-
|
188
|
+
std::string str_mq(mq->to_string(ctx.c_options));
|
189
|
+
char* str = sass_strdup(str_mq.c_str());
|
190
|
+
ctx.strings.push_back(str);
|
191
|
+
Parser p(Parser::from_c_str(str, ctx, mq->pstate()));
|
192
|
+
mq = p.parse_media_queries();
|
183
193
|
Media_Block* mm = SASS_MEMORY_NEW(ctx.mem, Media_Block,
|
184
194
|
m->pstate(),
|
185
|
-
static_cast<List*>(mq),
|
195
|
+
static_cast<List*>(mq->perform(&eval)),
|
186
196
|
m->block()->perform(this)->block(),
|
187
197
|
0);
|
188
198
|
mm->tabs(m->tabs());
|
@@ -318,6 +328,11 @@ namespace Sass {
|
|
318
328
|
|
319
329
|
Statement* Expand::operator()(Import_Stub* i)
|
320
330
|
{
|
331
|
+
// get parent node from call stack
|
332
|
+
AST_Node* parent = call_stack.back();
|
333
|
+
if (parent && dynamic_cast<Block*>(parent) == NULL) {
|
334
|
+
error("Import directives may not be used within control directives or mixins.", i->pstate());
|
335
|
+
}
|
321
336
|
// we don't seem to need that actually afterall
|
322
337
|
Sass_Import_Entry import = sass_make_import(
|
323
338
|
i->imp_path().c_str(),
|
@@ -355,12 +370,18 @@ namespace Sass {
|
|
355
370
|
|
356
371
|
Statement* Expand::operator()(Comment* c)
|
357
372
|
{
|
373
|
+
eval.is_in_comment = true;
|
374
|
+
auto rv = SASS_MEMORY_NEW(ctx.mem, Comment, c->pstate(), static_cast<String*>(c->text()->perform(&eval)), c->is_important());
|
375
|
+
eval.is_in_comment = false;
|
358
376
|
// TODO: eval the text, once we're parsing/storing it as a String_Schema
|
359
|
-
return
|
377
|
+
return rv;
|
360
378
|
}
|
361
379
|
|
362
380
|
Statement* Expand::operator()(If* i)
|
363
381
|
{
|
382
|
+
Env env(environment(), true);
|
383
|
+
env_stack.push_back(&env);
|
384
|
+
call_stack.push_back(i);
|
364
385
|
if (*i->predicate()->perform(&eval)) {
|
365
386
|
append_block(i->block());
|
366
387
|
}
|
@@ -368,6 +389,8 @@ namespace Sass {
|
|
368
389
|
Block* alt = i->alternative();
|
369
390
|
if (alt) append_block(alt);
|
370
391
|
}
|
392
|
+
call_stack.pop_back();
|
393
|
+
env_stack.pop_back();
|
371
394
|
return 0;
|
372
395
|
}
|
373
396
|
|
@@ -378,11 +401,11 @@ namespace Sass {
|
|
378
401
|
std::string variable(f->variable());
|
379
402
|
Expression* low = f->lower_bound()->perform(&eval);
|
380
403
|
if (low->concrete_type() != Expression::NUMBER) {
|
381
|
-
|
404
|
+
throw Exception::TypeMismatch(*low, "integer");
|
382
405
|
}
|
383
406
|
Expression* high = f->upper_bound()->perform(&eval);
|
384
407
|
if (high->concrete_type() != Expression::NUMBER) {
|
385
|
-
|
408
|
+
throw Exception::TypeMismatch(*high, "integer");
|
386
409
|
}
|
387
410
|
Number* sass_start = static_cast<Number*>(low);
|
388
411
|
Number* sass_end = static_cast<Number*>(high);
|
@@ -396,10 +419,11 @@ namespace Sass {
|
|
396
419
|
double start = sass_start->value();
|
397
420
|
double end = sass_end->value();
|
398
421
|
// only create iterator once in this environment
|
399
|
-
Env
|
400
|
-
|
401
|
-
|
402
|
-
env->
|
422
|
+
Env env(environment(), true);
|
423
|
+
env_stack.push_back(&env);
|
424
|
+
call_stack.push_back(f);
|
425
|
+
Number* it = SASS_MEMORY_NEW(env.mem, Number, low->pstate(), start, sass_end->unit());
|
426
|
+
env.set_local(variable, it);
|
403
427
|
Block* body = f->block();
|
404
428
|
if (start < end) {
|
405
429
|
if (f->is_inclusive()) ++end;
|
@@ -407,7 +431,7 @@ namespace Sass {
|
|
407
431
|
i < end;
|
408
432
|
++i) {
|
409
433
|
it->value(i);
|
410
|
-
env
|
434
|
+
env.set_local(variable, it);
|
411
435
|
append_block(body);
|
412
436
|
}
|
413
437
|
} else {
|
@@ -416,13 +440,12 @@ namespace Sass {
|
|
416
440
|
i > end;
|
417
441
|
--i) {
|
418
442
|
it->value(i);
|
419
|
-
env
|
443
|
+
env.set_local(variable, it);
|
420
444
|
append_block(body);
|
421
445
|
}
|
422
446
|
}
|
423
|
-
|
424
|
-
|
425
|
-
else env->set_local(variable, old_var);
|
447
|
+
call_stack.pop_back();
|
448
|
+
env_stack.pop_back();
|
426
449
|
return 0;
|
427
450
|
}
|
428
451
|
|
@@ -432,11 +455,15 @@ namespace Sass {
|
|
432
455
|
{
|
433
456
|
std::vector<std::string> variables(e->variables());
|
434
457
|
Expression* expr = e->list()->perform(&eval);
|
435
|
-
|
458
|
+
Vectorized<Expression*>* list = 0;
|
436
459
|
Map* map = 0;
|
437
460
|
if (expr->concrete_type() == Expression::MAP) {
|
438
461
|
map = static_cast<Map*>(expr);
|
439
462
|
}
|
463
|
+
else if (Selector_List* ls = dynamic_cast<Selector_List*>(expr)) {
|
464
|
+
Listize listize(ctx.mem);
|
465
|
+
list = dynamic_cast<List*>(ls->perform(&listize));
|
466
|
+
}
|
440
467
|
else if (expr->concrete_type() != Expression::LIST) {
|
441
468
|
list = SASS_MEMORY_NEW(ctx.mem, List, expr->pstate(), 1, SASS_COMMA);
|
442
469
|
*list << expr;
|
@@ -445,12 +472,9 @@ namespace Sass {
|
|
445
472
|
list = static_cast<List*>(expr);
|
446
473
|
}
|
447
474
|
// remember variables and then reset them
|
448
|
-
Env
|
449
|
-
|
450
|
-
|
451
|
-
old_vars[i] = env->has_local(variables[i]) ? env->get_local(variables[i]) : 0;
|
452
|
-
env->set_local(variables[i], 0);
|
453
|
-
}
|
475
|
+
Env env(environment(), true);
|
476
|
+
env_stack.push_back(&env);
|
477
|
+
call_stack.push_back(e);
|
454
478
|
Block* body = e->block();
|
455
479
|
|
456
480
|
if (map) {
|
@@ -462,16 +486,19 @@ namespace Sass {
|
|
462
486
|
List* variable = SASS_MEMORY_NEW(ctx.mem, List, map->pstate(), 2, SASS_SPACE);
|
463
487
|
*variable << k;
|
464
488
|
*variable << v;
|
465
|
-
env
|
489
|
+
env.set_local(variables[0], variable);
|
466
490
|
} else {
|
467
|
-
env
|
468
|
-
env
|
491
|
+
env.set_local(variables[0], k);
|
492
|
+
env.set_local(variables[1], v);
|
469
493
|
}
|
470
494
|
append_block(body);
|
471
495
|
}
|
472
496
|
}
|
473
497
|
else {
|
474
|
-
bool arglist = list->is_arglist();
|
498
|
+
// bool arglist = list->is_arglist();
|
499
|
+
if (list->length() == 1 && dynamic_cast<Selector_List*>(list)) {
|
500
|
+
list = dynamic_cast<Vectorized<Expression*>*>(list);
|
501
|
+
}
|
475
502
|
for (size_t i = 0, L = list->length(); i < L; ++i) {
|
476
503
|
Expression* e = (*list)[i];
|
477
504
|
// unwrap value if the expression is an argument
|
@@ -480,33 +507,30 @@ namespace Sass {
|
|
480
507
|
if (List* scalars = dynamic_cast<List*>(e)) {
|
481
508
|
if (variables.size() == 1) {
|
482
509
|
Expression* var = scalars;
|
483
|
-
if (arglist) var = (*scalars)[0];
|
484
|
-
env
|
510
|
+
// if (arglist) var = (*scalars)[0];
|
511
|
+
env.set_local(variables[0], var);
|
485
512
|
} else {
|
486
513
|
for (size_t j = 0, K = variables.size(); j < K; ++j) {
|
487
514
|
Expression* res = j >= scalars->length()
|
488
515
|
? SASS_MEMORY_NEW(ctx.mem, Null, expr->pstate())
|
489
516
|
: (*scalars)[j]->perform(&eval);
|
490
|
-
env
|
517
|
+
env.set_local(variables[j], res);
|
491
518
|
}
|
492
519
|
}
|
493
520
|
} else {
|
494
521
|
if (variables.size() > 0) {
|
495
|
-
env
|
522
|
+
env.set_local(variables[0], e);
|
496
523
|
for (size_t j = 1, K = variables.size(); j < K; ++j) {
|
497
524
|
Expression* res = SASS_MEMORY_NEW(ctx.mem, Null, expr->pstate());
|
498
|
-
env
|
525
|
+
env.set_local(variables[j], res);
|
499
526
|
}
|
500
527
|
}
|
501
528
|
}
|
502
529
|
append_block(body);
|
503
530
|
}
|
504
531
|
}
|
505
|
-
|
506
|
-
|
507
|
-
if(!old_vars[j]) env->del_local(variables[j]);
|
508
|
-
else env->set_local(variables[j], old_vars[j]);
|
509
|
-
}
|
532
|
+
call_stack.pop_back();
|
533
|
+
env_stack.pop_back();
|
510
534
|
return 0;
|
511
535
|
}
|
512
536
|
|
@@ -514,9 +538,14 @@ namespace Sass {
|
|
514
538
|
{
|
515
539
|
Expression* pred = w->predicate();
|
516
540
|
Block* body = w->block();
|
541
|
+
Env env(environment(), true);
|
542
|
+
env_stack.push_back(&env);
|
543
|
+
call_stack.push_back(w);
|
517
544
|
while (*pred->perform(&eval)) {
|
518
545
|
append_block(body);
|
519
546
|
}
|
547
|
+
call_stack.pop_back();
|
548
|
+
env_stack.pop_back();
|
520
549
|
return 0;
|
521
550
|
}
|
522
551
|
|
@@ -526,20 +555,16 @@ namespace Sass {
|
|
526
555
|
return 0;
|
527
556
|
}
|
528
557
|
|
529
|
-
Statement* Expand::operator()(Extension* e)
|
530
|
-
{
|
531
|
-
To_String to_string(&ctx);
|
532
|
-
Selector_List* extender = dynamic_cast<Selector_List*>(selector());
|
533
|
-
if (!extender) return 0;
|
534
|
-
selector_stack.push_back(0);
|
535
558
|
|
536
|
-
|
537
|
-
|
559
|
+
void Expand::expand_selector_list(Selector* s, Selector_List* extender) {
|
560
|
+
|
561
|
+
if (Selector_List* sl = dynamic_cast<Selector_List*>(s)) {
|
562
|
+
for (Complex_Selector* complex_selector : sl->elements()) {
|
538
563
|
Complex_Selector* tail = complex_selector;
|
539
564
|
while (tail) {
|
540
565
|
if (tail->head()) for (Simple_Selector* header : tail->head()->elements()) {
|
541
566
|
if (dynamic_cast<Parent_Selector*>(header) == NULL) continue; // skip all others
|
542
|
-
|
567
|
+
std::string sel_str(complex_selector->to_string(ctx.c_options));
|
543
568
|
error("Can't extend " + sel_str + ": can't extend parent selectors", header->pstate(), backtrace());
|
544
569
|
}
|
545
570
|
tail = tail->tail();
|
@@ -547,16 +572,17 @@ namespace Sass {
|
|
547
572
|
}
|
548
573
|
}
|
549
574
|
|
550
|
-
|
551
|
-
|
575
|
+
|
576
|
+
Selector_List* contextualized = dynamic_cast<Selector_List*>(s->perform(&eval));
|
577
|
+
if (contextualized == NULL) return;
|
552
578
|
for (auto complex_sel : contextualized->elements()) {
|
553
579
|
Complex_Selector* c = complex_sel;
|
554
580
|
if (!c->head() || c->tail()) {
|
555
|
-
|
581
|
+
std::string sel_str(contextualized->to_string(ctx.c_options));
|
556
582
|
error("Can't extend " + sel_str + ": can't extend nested selectors", c->pstate(), backtrace());
|
557
583
|
}
|
558
584
|
Compound_Selector* placeholder = c->head();
|
559
|
-
placeholder->is_optional(
|
585
|
+
placeholder->is_optional(s->is_optional());
|
560
586
|
for (size_t i = 0, L = extender->length(); i < L; ++i) {
|
561
587
|
Complex_Selector* sel = (*extender)[i];
|
562
588
|
if (!(sel->head() && sel->head()->length() > 0 &&
|
@@ -579,8 +605,16 @@ namespace Sass {
|
|
579
605
|
}
|
580
606
|
}
|
581
607
|
|
582
|
-
|
608
|
+
}
|
583
609
|
|
610
|
+
Statement* Expand::operator()(Extension* e)
|
611
|
+
{
|
612
|
+
if (Selector_List* extender = dynamic_cast<Selector_List*>(selector())) {
|
613
|
+
selector_stack.push_back(0);
|
614
|
+
Selector* s = e->selector();
|
615
|
+
expand_selector_list(s, extender);
|
616
|
+
selector_stack.pop_back();
|
617
|
+
}
|
584
618
|
return 0;
|
585
619
|
}
|
586
620
|
|
@@ -680,10 +714,12 @@ namespace Sass {
|
|
680
714
|
// process and add to last block on stack
|
681
715
|
inline void Expand::append_block(Block* b)
|
682
716
|
{
|
717
|
+
if (b->is_root()) call_stack.push_back(b);
|
683
718
|
for (size_t i = 0, L = b->length(); i < L; ++i) {
|
684
719
|
Statement* ith = (*b)[i]->perform(this);
|
685
720
|
if (ith) *block_stack.back() << ith;
|
686
721
|
}
|
722
|
+
if (b->is_root()) call_stack.pop_back();
|
687
723
|
}
|
688
724
|
|
689
725
|
}
|
data/ext/libsass/src/expand.hpp
CHANGED
@@ -30,6 +30,7 @@ namespace Sass {
|
|
30
30
|
// it's easier to work with vectors
|
31
31
|
std::vector<Env*> env_stack;
|
32
32
|
std::vector<Block*> block_stack;
|
33
|
+
std::vector<AST_Node*> call_stack;
|
33
34
|
std::vector<String*> property_stack;
|
34
35
|
std::vector<Selector_List*> selector_stack;
|
35
36
|
std::vector<Backtrace*>backtrace_stack;
|
@@ -37,11 +38,12 @@ namespace Sass {
|
|
37
38
|
|
38
39
|
Statement* fallback_impl(AST_Node* n);
|
39
40
|
|
41
|
+
private:
|
42
|
+
void expand_selector_list(Selector*, Selector_List* extender);
|
43
|
+
|
40
44
|
public:
|
41
45
|
Expand(Context&, Env*, Backtrace*);
|
42
|
-
|
43
|
-
|
44
|
-
using Operation<Statement*>::operator();
|
46
|
+
~Expand() { }
|
45
47
|
|
46
48
|
Statement* operator()(Block*);
|
47
49
|
Statement* operator()(Ruleset*);
|
data/ext/libsass/src/extend.cpp
CHANGED
@@ -1,10 +1,6 @@
|
|
1
|
-
#
|
2
|
-
#pragma warning(disable : 4503)
|
3
|
-
#endif
|
4
|
-
|
1
|
+
#include "sass.hpp"
|
5
2
|
#include "extend.hpp"
|
6
3
|
#include "context.hpp"
|
7
|
-
#include "to_string.hpp"
|
8
4
|
#include "backtrace.hpp"
|
9
5
|
#include "paths.hpp"
|
10
6
|
#include "parser.hpp"
|
@@ -85,23 +81,20 @@ namespace Sass {
|
|
85
81
|
|
86
82
|
|
87
83
|
std::ostream& operator<<(std::ostream& os, Compound_Selector& compoundSelector) {
|
88
|
-
To_String to_string;
|
89
84
|
for (size_t i = 0, L = compoundSelector.length(); i < L; ++i) {
|
90
85
|
if (i > 0) os << ", ";
|
91
|
-
os << compoundSelector[i]->
|
86
|
+
os << compoundSelector[i]->to_string();
|
92
87
|
}
|
93
88
|
return os;
|
94
89
|
}
|
95
90
|
|
96
91
|
std::ostream& operator<<(std::ostream& os, Simple_Selector& simpleSelector) {
|
97
|
-
|
98
|
-
os << simpleSelector.perform(&to_string);
|
92
|
+
os << simpleSelector.to_string();
|
99
93
|
return os;
|
100
94
|
}
|
101
95
|
|
102
96
|
// Print a string representation of a Compound_Selector
|
103
97
|
static void printSimpleSelector(Simple_Selector* pSimpleSelector, const char* message=NULL, bool newline=true) {
|
104
|
-
To_String to_string;
|
105
98
|
|
106
99
|
if (message) {
|
107
100
|
std::cerr << message;
|
@@ -125,7 +118,6 @@ namespace Sass {
|
|
125
118
|
|
126
119
|
// Print a string representation of a Compound_Selector
|
127
120
|
static void printCompoundSelector(Compound_Selector* pCompoundSelector, const char* message=NULL, bool newline=true) {
|
128
|
-
To_String to_string;
|
129
121
|
|
130
122
|
if (message) {
|
131
123
|
std::cerr << message;
|
@@ -144,7 +136,6 @@ namespace Sass {
|
|
144
136
|
|
145
137
|
|
146
138
|
std::ostream& operator<<(std::ostream& os, Complex_Selector& complexSelector) {
|
147
|
-
To_String to_string;
|
148
139
|
|
149
140
|
os << "[";
|
150
141
|
Complex_Selector* pIter = &complexSelector;
|
@@ -164,7 +155,7 @@ namespace Sass {
|
|
164
155
|
first = false;
|
165
156
|
|
166
157
|
if (pIter->head()) {
|
167
|
-
os << pIter->head()->
|
158
|
+
os << pIter->head()->to_string();
|
168
159
|
} else {
|
169
160
|
os << "NULL_HEAD";
|
170
161
|
}
|
@@ -179,7 +170,6 @@ namespace Sass {
|
|
179
170
|
|
180
171
|
// Print a string representation of a Complex_Selector
|
181
172
|
static void printComplexSelector(Complex_Selector* pComplexSelector, const char* message=NULL, bool newline=true) {
|
182
|
-
To_String to_string;
|
183
173
|
|
184
174
|
if (message) {
|
185
175
|
std::cerr << message;
|
@@ -197,7 +187,6 @@ namespace Sass {
|
|
197
187
|
}
|
198
188
|
|
199
189
|
static void printSelsNewSeqPairCollection(SelsNewSeqPairCollection& collection, const char* message=NULL, bool newline=true) {
|
200
|
-
To_String to_string;
|
201
190
|
|
202
191
|
if (message) {
|
203
192
|
std::cerr << message;
|
@@ -225,7 +214,6 @@ namespace Sass {
|
|
225
214
|
|
226
215
|
// Print a string representation of a SourcesSet
|
227
216
|
static void printSourcesSet(SourcesSet& sources, Context& ctx, const char* message=NULL, bool newline=true) {
|
228
|
-
To_String to_string;
|
229
217
|
|
230
218
|
if (message) {
|
231
219
|
std::cerr << message;
|
@@ -1558,8 +1546,6 @@ namespace Sass {
|
|
1558
1546
|
Node extendedSelectors = Node::createCollection();
|
1559
1547
|
// extendedSelectors.got_line_feed = true;
|
1560
1548
|
|
1561
|
-
To_String to_string;
|
1562
|
-
|
1563
1549
|
SubsetMapEntries entries = subset_map.get_v(pSelector->to_str_vec());
|
1564
1550
|
|
1565
1551
|
typedef std::vector<std::pair<Complex_Selector, std::vector<ExtensionPair> > > GroupedByToAResult;
|
@@ -1591,6 +1577,7 @@ namespace Sass {
|
|
1591
1577
|
for (size_t index = 0; index < pCompound->length(); index++) {
|
1592
1578
|
Simple_Selector* pSimpleSelector = (*pCompound)[index];
|
1593
1579
|
(*pSels) << pSimpleSelector;
|
1580
|
+
pCompound->extended(true);
|
1594
1581
|
}
|
1595
1582
|
}
|
1596
1583
|
|
@@ -1732,18 +1719,32 @@ namespace Sass {
|
|
1732
1719
|
Compound_Selector* pHead = pIter->head();
|
1733
1720
|
|
1734
1721
|
if (pHead) {
|
1722
|
+
for (Simple_Selector* pSimple : *pHead) {
|
1723
|
+
if (Wrapped_Selector* ws = dynamic_cast<Wrapped_Selector*>(pSimple)) {
|
1724
|
+
if (Selector_List* sl = dynamic_cast<Selector_List*>(ws->selector())) {
|
1725
|
+
for (Complex_Selector* cs : sl->elements()) {
|
1726
|
+
while (cs) {
|
1727
|
+
if (complexSelectorHasExtension(cs, ctx, subset_map)) {
|
1728
|
+
hasExtension = true;
|
1729
|
+
break;
|
1730
|
+
}
|
1731
|
+
cs = cs->tail();
|
1732
|
+
}
|
1733
|
+
}
|
1734
|
+
}
|
1735
|
+
}
|
1736
|
+
}
|
1735
1737
|
SubsetMapEntries entries = subset_map.get_v(pHead->to_str_vec());
|
1736
1738
|
for (ExtensionPair ext : entries) {
|
1737
1739
|
// check if both selectors have the same media block parent
|
1738
1740
|
if (ext.first->media_block() == pComplexSelector->media_block()) continue;
|
1739
|
-
To_String to_string(&ctx);
|
1740
1741
|
if (ext.second->media_block() == 0) continue;
|
1741
1742
|
if (pComplexSelector->media_block() &&
|
1742
1743
|
ext.second->media_block()->media_queries() &&
|
1743
1744
|
pComplexSelector->media_block()->media_queries()
|
1744
1745
|
) {
|
1745
|
-
std::string query_left(ext.second->media_block()->media_queries()->
|
1746
|
-
std::string query_right(pComplexSelector->media_block()->media_queries()->
|
1746
|
+
std::string query_left(ext.second->media_block()->media_queries()->to_string(ctx.c_options));
|
1747
|
+
std::string query_right(pComplexSelector->media_block()->media_queries()->to_string(ctx.c_options));
|
1747
1748
|
if (query_left == query_right) continue;
|
1748
1749
|
}
|
1749
1750
|
|
@@ -1754,7 +1755,7 @@ namespace Sass {
|
|
1754
1755
|
std::string rel_path(Sass::File::abs2rel(pstate.path, cwd, cwd));
|
1755
1756
|
err << "You may not @extend an outer selector from within @media.\n";
|
1756
1757
|
err << "You may only @extend selectors within the same directive.\n";
|
1757
|
-
err << "From \"@extend " << ext.second->
|
1758
|
+
err << "From \"@extend " << ext.second->to_string(ctx.c_options) << "\"";
|
1758
1759
|
err << " on line " << pstate.line+1 << " of " << rel_path << "\n";
|
1759
1760
|
error(err.str(), pComplexSelector->pstate());
|
1760
1761
|
}
|
@@ -1764,29 +1765,6 @@ namespace Sass {
|
|
1764
1765
|
pIter = pIter->tail();
|
1765
1766
|
}
|
1766
1767
|
|
1767
|
-
if (!hasExtension) {
|
1768
|
-
/* ToDo: don't break stuff
|
1769
|
-
std::stringstream err;
|
1770
|
-
To_String to_string(&ctx);
|
1771
|
-
std::string cwd(Sass::File::get_cwd());
|
1772
|
-
std::string sel1(pComplexSelector->perform(&to_string));
|
1773
|
-
Compound_Selector* pExtendSelector = 0;
|
1774
|
-
for (auto i : subset_map.values()) {
|
1775
|
-
if (i.first == pComplexSelector) {
|
1776
|
-
pExtendSelector = i.second;
|
1777
|
-
break;
|
1778
|
-
}
|
1779
|
-
}
|
1780
|
-
if (!pExtendSelector || !pExtendSelector->is_optional()) {
|
1781
|
-
std::string sel2(pExtendSelector ? pExtendSelector->perform(&to_string) : "[unknown]");
|
1782
|
-
err << "\"" << sel1 << "\" failed to @extend \"" << sel2 << "\"\n";
|
1783
|
-
err << "The selector \"" << sel2 << "\" was not found.\n";
|
1784
|
-
err << "Use \"@extend " << sel2 << " !optional\" if the extend should be able to fail.";
|
1785
|
-
error(err.str(), pExtendSelector ? pExtendSelector->pstate() : pComplexSelector->pstate());
|
1786
|
-
}
|
1787
|
-
*/
|
1788
|
-
}
|
1789
|
-
|
1790
1768
|
return hasExtension;
|
1791
1769
|
}
|
1792
1770
|
|
@@ -1928,8 +1906,6 @@ namespace Sass {
|
|
1928
1906
|
*/
|
1929
1907
|
Selector_List* Extend::extendSelectorList(Selector_List* pSelectorList, Context& ctx, ExtensionSubsetMap& subset_map, bool isReplace, bool& extendedSomething) {
|
1930
1908
|
|
1931
|
-
To_String to_string(&ctx);
|
1932
|
-
|
1933
1909
|
Selector_List* pNewSelectors = SASS_MEMORY_NEW(ctx.mem, Selector_List, pSelectorList->pstate(), pSelectorList->length());
|
1934
1910
|
|
1935
1911
|
extendedSomething = false;
|
@@ -1967,6 +1943,21 @@ namespace Sass {
|
|
1967
1943
|
}
|
1968
1944
|
}
|
1969
1945
|
|
1946
|
+
for (Complex_Selector* cs : *pNewSelectors) {
|
1947
|
+
while (cs) {
|
1948
|
+
if (cs->head()) {
|
1949
|
+
for (Simple_Selector* ss : *cs->head()) {
|
1950
|
+
if (Wrapped_Selector* ws = dynamic_cast<Wrapped_Selector*>(ss)) {
|
1951
|
+
if (Selector_List* sl = dynamic_cast<Selector_List*>(ws->selector())) {
|
1952
|
+
bool extended = false;
|
1953
|
+
ws->selector(extendSelectorList(sl, ctx, subset_map, false, extended));
|
1954
|
+
}
|
1955
|
+
}
|
1956
|
+
}
|
1957
|
+
}
|
1958
|
+
cs = cs->tail();
|
1959
|
+
}
|
1960
|
+
}
|
1970
1961
|
return pNewSelectors;
|
1971
1962
|
|
1972
1963
|
}
|
@@ -2006,9 +1997,8 @@ namespace Sass {
|
|
2006
1997
|
// Extend a ruleset by extending the selectors and updating them on the ruleset. The block's rules don't need to change.
|
2007
1998
|
template <typename ObjectType>
|
2008
1999
|
static void extendObjectWithSelectorAndBlock(ObjectType* pObject, Context& ctx, ExtensionSubsetMap& subset_map) {
|
2009
|
-
To_String to_string(&ctx);
|
2010
2000
|
|
2011
|
-
DEBUG_PRINTLN(EXTEND_OBJECT, "FOUND SELECTOR: " << static_cast<Selector_List*>(pObject->selector())->
|
2001
|
+
DEBUG_PRINTLN(EXTEND_OBJECT, "FOUND SELECTOR: " << static_cast<Selector_List*>(pObject->selector())->to_string(ctx.c_options))
|
2012
2002
|
|
2013
2003
|
// Ruby sass seems to filter nodes that don't have any content well before we get here. I'm not sure the repercussions
|
2014
2004
|
// of doing so, so for now, let's just not extend things that won't be output later.
|
@@ -2021,8 +2011,8 @@ namespace Sass {
|
|
2021
2011
|
Selector_List* pNewSelectorList = Extend::extendSelectorList(static_cast<Selector_List*>(pObject->selector()), ctx, subset_map, false, extendedSomething);
|
2022
2012
|
|
2023
2013
|
if (extendedSomething && pNewSelectorList) {
|
2024
|
-
DEBUG_PRINTLN(EXTEND_OBJECT, "EXTEND ORIGINAL SELECTORS: " << static_cast<Selector_List*>(pObject->selector())->
|
2025
|
-
DEBUG_PRINTLN(EXTEND_OBJECT, "EXTEND SETTING NEW SELECTORS: " << pNewSelectorList->
|
2014
|
+
DEBUG_PRINTLN(EXTEND_OBJECT, "EXTEND ORIGINAL SELECTORS: " << static_cast<Selector_List*>(pObject->selector())->to_string(ctx.c_options))
|
2015
|
+
DEBUG_PRINTLN(EXTEND_OBJECT, "EXTEND SETTING NEW SELECTORS: " << pNewSelectorList->to_string(ctx.c_options))
|
2026
2016
|
pNewSelectorList->remove_parent_selectors();
|
2027
2017
|
pObject->selector(pNewSelectorList);
|
2028
2018
|
} else {
|
@@ -2041,6 +2031,25 @@ namespace Sass {
|
|
2041
2031
|
for (size_t i = 0, L = b->length(); i < L; ++i) {
|
2042
2032
|
(*b)[i]->perform(this);
|
2043
2033
|
}
|
2034
|
+
// do final check if everything was extended
|
2035
|
+
// we set `extended` flag on extended selectors
|
2036
|
+
if (b->is_root()) {
|
2037
|
+
// debug_subset_map(subset_map);
|
2038
|
+
for(auto const &it : subset_map.values()) {
|
2039
|
+
Complex_Selector* sel = it.first ? it.first->first() : NULL;
|
2040
|
+
Compound_Selector* ext = it.second ? it.second : NULL;
|
2041
|
+
if (ext && (ext->extended() || ext->is_optional())) continue;
|
2042
|
+
std::string str_sel(sel->to_string({ NESTED, 5 }));
|
2043
|
+
std::string str_ext(ext->to_string({ NESTED, 5 }));
|
2044
|
+
// debug_ast(sel, "sel: ");
|
2045
|
+
// debug_ast(ext, "ext: ");
|
2046
|
+
error("\"" + str_sel + "\" failed to @extend \"" + str_ext + "\".\n"
|
2047
|
+
"The selector \"" + str_ext + "\" was not found.\n"
|
2048
|
+
"Use \"@extend " + str_ext + " !optional\" if the"
|
2049
|
+
" extend should be able to fail.", ext->pstate());
|
2050
|
+
}
|
2051
|
+
}
|
2052
|
+
|
2044
2053
|
}
|
2045
2054
|
|
2046
2055
|
void Extend::operator()(Ruleset* pRuleset)
|