sassc 1.10.1 → 1.11.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 +5 -2
- data/ext/libsass/.github/CONTRIBUTING.md +65 -0
- data/ext/libsass/.github/ISSUE_TEMPLATE.md +29 -0
- data/ext/libsass/Makefile +8 -3
- data/ext/libsass/Makefile.conf +28 -22
- data/ext/libsass/Readme.md +14 -7
- data/ext/libsass/configure.ac +5 -8
- data/ext/libsass/docs/api-context-internal.md +3 -0
- data/ext/libsass/docs/api-context.md +7 -0
- data/ext/libsass/docs/api-doc.md +4 -0
- data/ext/libsass/docs/api-importer.md +2 -0
- data/ext/libsass/docs/api-value-example.md +55 -0
- data/ext/libsass/docs/api-value.md +49 -22
- data/ext/libsass/docs/implementations.md +4 -0
- data/ext/libsass/include/sass/base.h +5 -4
- data/ext/libsass/include/sass/context.h +3 -0
- data/ext/libsass/include/sass/values.h +28 -27
- data/ext/libsass/include/sass/version.h +1 -1
- data/ext/libsass/include/sass2scss.h +1 -1
- data/ext/libsass/script/ci-build-libsass +3 -3
- data/ext/libsass/script/ci-install-deps +12 -3
- data/ext/libsass/src/ast.cpp +321 -212
- data/ext/libsass/src/ast.hpp +273 -165
- data/ext/libsass/src/ast_factory.hpp +4 -5
- data/ext/libsass/src/ast_fwd_decl.hpp +8 -7
- data/ext/libsass/src/bind.cpp +2 -7
- data/ext/libsass/src/bind.hpp +0 -1
- data/ext/libsass/src/check_nesting.cpp +379 -0
- data/ext/libsass/src/check_nesting.hpp +60 -0
- data/ext/libsass/src/constants.cpp +7 -6
- data/ext/libsass/src/constants.hpp +2 -1
- data/ext/libsass/src/context.cpp +7 -1
- data/ext/libsass/src/context.hpp +1 -1
- data/ext/libsass/src/cssize.cpp +76 -32
- data/ext/libsass/src/cssize.hpp +7 -8
- data/ext/libsass/src/debugger.hpp +70 -40
- data/ext/libsass/src/error_handling.cpp +15 -2
- data/ext/libsass/src/error_handling.hpp +19 -0
- data/ext/libsass/src/eval.cpp +107 -161
- data/ext/libsass/src/eval.hpp +12 -8
- data/ext/libsass/src/expand.cpp +81 -74
- data/ext/libsass/src/expand.hpp +13 -12
- data/ext/libsass/src/extend.cpp +149 -142
- data/ext/libsass/src/extend.hpp +10 -3
- data/ext/libsass/src/file.cpp +2 -1
- data/ext/libsass/src/functions.cpp +96 -59
- data/ext/libsass/src/functions.hpp +2 -2
- data/ext/libsass/src/inspect.cpp +33 -45
- data/ext/libsass/src/inspect.hpp +7 -7
- data/ext/libsass/src/json.cpp +17 -5
- data/ext/libsass/src/lexer.cpp +3 -3
- data/ext/libsass/src/listize.cpp +10 -10
- data/ext/libsass/src/listize.hpp +3 -3
- data/ext/libsass/src/node.cpp +30 -30
- data/ext/libsass/src/node.hpp +13 -13
- data/ext/libsass/src/operation.hpp +21 -19
- data/ext/libsass/src/output.cpp +48 -103
- data/ext/libsass/src/output.hpp +0 -1
- data/ext/libsass/src/parser.cpp +161 -133
- data/ext/libsass/src/parser.hpp +10 -7
- data/ext/libsass/src/remove_placeholders.cpp +6 -6
- data/ext/libsass/src/remove_placeholders.hpp +1 -1
- data/ext/libsass/src/sass.cpp +21 -0
- data/ext/libsass/src/sass.hpp +8 -1
- data/ext/libsass/src/sass2scss.cpp +14 -3
- data/ext/libsass/src/sass_context.cpp +69 -24
- data/ext/libsass/src/sass_context.hpp +3 -0
- data/ext/libsass/src/source_map.cpp +22 -10
- data/ext/libsass/src/to_value.cpp +2 -2
- data/ext/libsass/src/to_value.hpp +1 -1
- data/ext/libsass/src/units.hpp +3 -1
- data/ext/libsass/src/util.cpp +20 -16
- data/ext/libsass/src/util.hpp +2 -1
- data/ext/libsass/win/libsass.targets +2 -0
- data/ext/libsass/win/libsass.vcxproj.filters +6 -0
- data/lib/sassc/engine.rb +5 -0
- data/lib/sassc/native/native_functions_api.rb +13 -1
- data/lib/sassc/script/value_conversion.rb +11 -1
- data/lib/sassc/script/value_conversion/list.rb +23 -0
- data/lib/sassc/version.rb +1 -1
- data/test/engine_test.rb +18 -2
- data/test/functions_test.rb +30 -0
- data/test/native_test.rb +1 -1
- metadata +8 -3
data/ext/libsass/src/ast.hpp
CHANGED
@@ -50,6 +50,9 @@
|
|
50
50
|
|
51
51
|
namespace Sass {
|
52
52
|
|
53
|
+
// easier to search with name
|
54
|
+
const bool DELAYED = true;
|
55
|
+
|
53
56
|
// ToDo: should this really be hardcoded
|
54
57
|
// Note: most methods follow precision option
|
55
58
|
const double NUMBER_EPSILON = 0.00000000000001;
|
@@ -67,7 +70,8 @@ namespace Sass {
|
|
67
70
|
bool ws_after;
|
68
71
|
};
|
69
72
|
|
70
|
-
|
73
|
+
//////////////////////////////////////////////////////////
|
74
|
+
// `hash_combine` comes from boost (functional/hash):
|
71
75
|
// http://www.boost.org/doc/libs/1_35_0/doc/html/hash/combine.html
|
72
76
|
// Boost Software License - Version 1.0
|
73
77
|
// http://www.boost.org/users/license.html
|
@@ -77,6 +81,7 @@ namespace Sass {
|
|
77
81
|
seed ^= std::hash<T>()(val) + 0x9e3779b9
|
78
82
|
+ (seed<<6) + (seed>>2);
|
79
83
|
}
|
84
|
+
//////////////////////////////////////////////////////////
|
80
85
|
|
81
86
|
//////////////////////////////////////////////////////////
|
82
87
|
// Abstract base class for all abstract syntax tree nodes.
|
@@ -96,6 +101,7 @@ namespace Sass {
|
|
96
101
|
// virtual Block* block() { return 0; }
|
97
102
|
public:
|
98
103
|
void update_pstate(const ParserState& pstate);
|
104
|
+
void set_pstate_offset(const Offset& offset);
|
99
105
|
public:
|
100
106
|
Offset off() { return pstate(); }
|
101
107
|
Position pos() { return pstate(); }
|
@@ -136,7 +142,7 @@ namespace Sass {
|
|
136
142
|
bool d = false, bool e = false, bool i = false, Concrete_Type ct = NONE)
|
137
143
|
: AST_Node(pstate),
|
138
144
|
is_delayed_(d),
|
139
|
-
is_expanded_(
|
145
|
+
is_expanded_(e),
|
140
146
|
is_interpolant_(i),
|
141
147
|
concrete_type_(ct)
|
142
148
|
{ }
|
@@ -147,6 +153,7 @@ namespace Sass {
|
|
147
153
|
static std::string type_name() { return ""; }
|
148
154
|
virtual bool is_false() { return false; }
|
149
155
|
virtual bool operator== (const Expression& rhs) const { return false; }
|
156
|
+
virtual bool eq(const Expression& rhs) const { return *this == rhs; };
|
150
157
|
virtual void set_delayed(bool delayed) { is_delayed(delayed); }
|
151
158
|
virtual bool has_interpolant() const { return is_interpolant(); }
|
152
159
|
virtual bool is_left_interpolant() const { return is_interpolant(); }
|
@@ -219,7 +226,7 @@ namespace Sass {
|
|
219
226
|
void reset_hash() { hash_ = 0; }
|
220
227
|
virtual void adjust_after_pushing(T element) { }
|
221
228
|
public:
|
222
|
-
Vectorized(size_t s = 0) : elements_(std::vector<T>())
|
229
|
+
Vectorized(size_t s = 0) : elements_(std::vector<T>()), hash_(0)
|
223
230
|
{ elements_.reserve(s); }
|
224
231
|
virtual ~Vectorized() = 0;
|
225
232
|
size_t length() const { return elements_.size(); }
|
@@ -229,7 +236,7 @@ namespace Sass {
|
|
229
236
|
T& operator[](size_t i) { return elements_[i]; }
|
230
237
|
virtual const T& at(size_t i) const { return elements_.at(i); }
|
231
238
|
const T& operator[](size_t i) const { return elements_[i]; }
|
232
|
-
Vectorized& operator<<(T element)
|
239
|
+
virtual Vectorized& operator<<(T element)
|
233
240
|
{
|
234
241
|
if (!element) return *this;
|
235
242
|
reset_hash();
|
@@ -284,7 +291,7 @@ namespace Sass {
|
|
284
291
|
};
|
285
292
|
struct CompareExpression {
|
286
293
|
bool operator()(const Expression* lhs, const Expression* rhs) const {
|
287
|
-
return lhs && rhs &&
|
294
|
+
return lhs && rhs && lhs->eq(*rhs);
|
288
295
|
}
|
289
296
|
};
|
290
297
|
typedef std::unordered_map<
|
@@ -391,11 +398,10 @@ namespace Sass {
|
|
391
398
|
ADD_PROPERTY(bool, group_end)
|
392
399
|
public:
|
393
400
|
Statement(ParserState pstate, Statement_Type st = NONE, size_t t = 0)
|
394
|
-
: AST_Node(pstate), statement_type_(st), tabs_(t), group_end_(false)
|
401
|
+
: AST_Node(pstate), block_(0), statement_type_(st), tabs_(t), group_end_(false)
|
395
402
|
{ }
|
396
403
|
virtual ~Statement() = 0;
|
397
404
|
// needed for rearranging nested rulesets during CSS emission
|
398
|
-
virtual bool is_hoistable() { return false; }
|
399
405
|
virtual bool is_invisible() const { return false; }
|
400
406
|
virtual bool bubbles() { return false; }
|
401
407
|
virtual Block* block() { return 0; }
|
@@ -413,22 +419,16 @@ namespace Sass {
|
|
413
419
|
ADD_PROPERTY(bool, is_root)
|
414
420
|
ADD_PROPERTY(bool, is_at_root);
|
415
421
|
// needed for properly formatted CSS emission
|
416
|
-
ADD_PROPERTY(bool, has_hoistable)
|
417
|
-
ADD_PROPERTY(bool, has_non_hoistable)
|
418
422
|
protected:
|
419
423
|
void adjust_after_pushing(Statement* s)
|
420
424
|
{
|
421
|
-
if (s->is_hoistable()) has_hoistable_ = true;
|
422
|
-
else has_non_hoistable_ = true;
|
423
425
|
}
|
424
426
|
public:
|
425
427
|
Block(ParserState pstate, size_t s = 0, bool r = false)
|
426
428
|
: Statement(pstate),
|
427
429
|
Vectorized<Statement*>(s),
|
428
430
|
is_root_(r),
|
429
|
-
is_at_root_(false)
|
430
|
-
has_hoistable_(false),
|
431
|
-
has_non_hoistable_(false)
|
431
|
+
is_at_root_(false)
|
432
432
|
{ }
|
433
433
|
virtual bool has_content()
|
434
434
|
{
|
@@ -471,20 +471,6 @@ namespace Sass {
|
|
471
471
|
: Has_Block(pstate, b), selector_(s), at_root_(false), is_root_(false)
|
472
472
|
{ statement_type(RULESET); }
|
473
473
|
bool is_invisible() const;
|
474
|
-
// nested rulesets need to be hoisted out of their enclosing blocks
|
475
|
-
bool is_hoistable() { return true; }
|
476
|
-
ATTACH_OPERATIONS()
|
477
|
-
};
|
478
|
-
|
479
|
-
/////////////////////////////////////////////////////////
|
480
|
-
// Nested declaration sets (i.e., namespaced properties).
|
481
|
-
/////////////////////////////////////////////////////////
|
482
|
-
class Propset : public Has_Block {
|
483
|
-
ADD_PROPERTY(String*, property_fragment)
|
484
|
-
public:
|
485
|
-
Propset(ParserState pstate, String* pf, Block* b = 0)
|
486
|
-
: Has_Block(pstate, b), property_fragment_(pf)
|
487
|
-
{ }
|
488
474
|
ATTACH_OPERATIONS()
|
489
475
|
};
|
490
476
|
|
@@ -502,6 +488,18 @@ namespace Sass {
|
|
502
488
|
ATTACH_OPERATIONS()
|
503
489
|
};
|
504
490
|
|
491
|
+
/////////////////
|
492
|
+
// Trace.
|
493
|
+
/////////////////
|
494
|
+
class Trace : public Has_Block {
|
495
|
+
ADD_PROPERTY(std::string, name)
|
496
|
+
public:
|
497
|
+
Trace(ParserState pstate, std::string n, Block* b = 0)
|
498
|
+
: Has_Block(pstate, b), name_(n)
|
499
|
+
{ }
|
500
|
+
ATTACH_OPERATIONS()
|
501
|
+
};
|
502
|
+
|
505
503
|
/////////////////
|
506
504
|
// Media queries.
|
507
505
|
/////////////////
|
@@ -515,7 +513,6 @@ namespace Sass {
|
|
515
513
|
: Has_Block(pstate, b), media_queries_(mqs)
|
516
514
|
{ statement_type(MEDIA); }
|
517
515
|
bool bubbles() { return true; }
|
518
|
-
bool is_hoistable() { return true; }
|
519
516
|
bool is_invisible() const;
|
520
517
|
ATTACH_OPERATIONS()
|
521
518
|
};
|
@@ -563,15 +560,15 @@ namespace Sass {
|
|
563
560
|
////////////////////////////////////////////////////////////////////////
|
564
561
|
// Declarations -- style rules consisting of a property name and values.
|
565
562
|
////////////////////////////////////////////////////////////////////////
|
566
|
-
class Declaration : public
|
563
|
+
class Declaration : public Has_Block {
|
567
564
|
ADD_PROPERTY(String*, property)
|
568
565
|
ADD_PROPERTY(Expression*, value)
|
569
566
|
ADD_PROPERTY(bool, is_important)
|
570
567
|
ADD_PROPERTY(bool, is_indented)
|
571
568
|
public:
|
572
569
|
Declaration(ParserState pstate,
|
573
|
-
String* prop, Expression* val, bool i = false)
|
574
|
-
:
|
570
|
+
String* prop, Expression* val, bool i = false, Block* b = 0)
|
571
|
+
: Has_Block(pstate, b), property_(prop), value_(val), is_important_(i), is_indented_(false)
|
575
572
|
{ statement_type(DECLARATION); }
|
576
573
|
ATTACH_OPERATIONS()
|
577
574
|
};
|
@@ -770,7 +767,7 @@ namespace Sass {
|
|
770
767
|
struct Backtrace;
|
771
768
|
typedef Environment<AST_Node*> Env;
|
772
769
|
typedef const char* Signature;
|
773
|
-
typedef Expression* (*Native_Function)(Env&, Env&, Context&, Signature, ParserState, Backtrace
|
770
|
+
typedef Expression* (*Native_Function)(Env&, Env&, Context&, Signature, ParserState, Backtrace*, std::vector<CommaSequence_Selector*>);
|
774
771
|
typedef const char* Signature;
|
775
772
|
class Definition : public Has_Block {
|
776
773
|
public:
|
@@ -905,9 +902,8 @@ namespace Sass {
|
|
905
902
|
|
906
903
|
virtual void set_delayed(bool delayed)
|
907
904
|
{
|
908
|
-
for (size_t i = 0, L = length(); i < L; ++i)
|
909
|
-
(elements()[i])->set_delayed(delayed);
|
910
905
|
is_delayed(delayed);
|
906
|
+
// don't set children
|
911
907
|
}
|
912
908
|
|
913
909
|
virtual bool operator== (const Expression& rhs) const;
|
@@ -929,6 +925,7 @@ namespace Sass {
|
|
929
925
|
std::string type() { return "map"; }
|
930
926
|
static std::string type_name() { return "map"; }
|
931
927
|
bool is_invisible() const { return empty(); }
|
928
|
+
List* to_list(Context& ctx, ParserState& pstate);
|
932
929
|
|
933
930
|
virtual size_t hash()
|
934
931
|
{
|
@@ -1031,12 +1028,6 @@ namespace Sass {
|
|
1031
1028
|
return is_left_interpolant() ||
|
1032
1029
|
is_right_interpolant();
|
1033
1030
|
}
|
1034
|
-
virtual bool can_delay() const;
|
1035
|
-
void reset_whitespace()
|
1036
|
-
{
|
1037
|
-
op_.ws_before = false;
|
1038
|
-
op_.ws_after = false;
|
1039
|
-
}
|
1040
1031
|
virtual void set_delayed(bool delayed)
|
1041
1032
|
{
|
1042
1033
|
right()->set_delayed(delayed);
|
@@ -1138,6 +1129,7 @@ namespace Sass {
|
|
1138
1129
|
}
|
1139
1130
|
}
|
1140
1131
|
|
1132
|
+
virtual void set_delayed(bool delayed);
|
1141
1133
|
virtual bool operator==(const Expression& rhs) const
|
1142
1134
|
{
|
1143
1135
|
try
|
@@ -1185,6 +1177,8 @@ namespace Sass {
|
|
1185
1177
|
has_keyword_argument_(false)
|
1186
1178
|
{ }
|
1187
1179
|
|
1180
|
+
virtual void set_delayed(bool delayed);
|
1181
|
+
|
1188
1182
|
Argument* get_rest_argument();
|
1189
1183
|
Argument* get_keyword_argument();
|
1190
1184
|
|
@@ -1296,7 +1290,7 @@ namespace Sass {
|
|
1296
1290
|
size_t hash_;
|
1297
1291
|
public:
|
1298
1292
|
Textual(ParserState pstate, Type t, std::string val)
|
1299
|
-
: Expression(pstate,
|
1293
|
+
: Expression(pstate, DELAYED), type_(t), value_(val),
|
1300
1294
|
hash_(0)
|
1301
1295
|
{ }
|
1302
1296
|
|
@@ -1368,6 +1362,7 @@ namespace Sass {
|
|
1368
1362
|
|
1369
1363
|
virtual bool operator< (const Number& rhs) const;
|
1370
1364
|
virtual bool operator== (const Expression& rhs) const;
|
1365
|
+
virtual bool eq(const Expression& rhs) const;
|
1371
1366
|
|
1372
1367
|
ATTACH_OPERATIONS()
|
1373
1368
|
};
|
@@ -1466,10 +1461,9 @@ namespace Sass {
|
|
1466
1461
|
// "flat" strings.
|
1467
1462
|
////////////////////////////////////////////////////////////////////////
|
1468
1463
|
class String : public Value {
|
1469
|
-
ADD_PROPERTY(bool, sass_fix_1291)
|
1470
1464
|
public:
|
1471
|
-
String(ParserState pstate, bool delayed = false
|
1472
|
-
: Value(pstate, delayed)
|
1465
|
+
String(ParserState pstate, bool delayed = false)
|
1466
|
+
: Value(pstate, delayed)
|
1473
1467
|
{ concrete_type(STRING); }
|
1474
1468
|
static std::string type_name() { return "string"; }
|
1475
1469
|
virtual ~String() = 0;
|
@@ -1517,6 +1511,10 @@ namespace Sass {
|
|
1517
1511
|
return hash_;
|
1518
1512
|
}
|
1519
1513
|
|
1514
|
+
virtual void set_delayed(bool delayed) {
|
1515
|
+
is_delayed(delayed);
|
1516
|
+
}
|
1517
|
+
|
1520
1518
|
virtual bool operator==(const Expression& rhs) const;
|
1521
1519
|
|
1522
1520
|
ATTACH_OPERATIONS()
|
@@ -1574,10 +1572,14 @@ namespace Sass {
|
|
1574
1572
|
////////////////////////////////////////////////////////
|
1575
1573
|
class String_Quoted : public String_Constant {
|
1576
1574
|
public:
|
1577
|
-
String_Quoted(ParserState pstate, std::string val, char q = 0,
|
1575
|
+
String_Quoted(ParserState pstate, std::string val, char q = 0,
|
1576
|
+
bool keep_utf8_escapes = false, bool skip_unquoting = false,
|
1577
|
+
bool strict_unquoting = true)
|
1578
1578
|
: String_Constant(pstate, val)
|
1579
1579
|
{
|
1580
|
-
|
1580
|
+
if (skip_unquoting == false) {
|
1581
|
+
value_ = unquote(value_, "e_mark_, keep_utf8_escapes, strict_unquoting);
|
1582
|
+
}
|
1581
1583
|
if (q && quote_mark_) quote_mark_ = q;
|
1582
1584
|
}
|
1583
1585
|
virtual bool operator==(const Expression& rhs) const;
|
@@ -1626,7 +1628,6 @@ namespace Sass {
|
|
1626
1628
|
Supports_Block(ParserState pstate, Supports_Condition* condition, Block* block = 0)
|
1627
1629
|
: Has_Block(pstate, block), condition_(condition)
|
1628
1630
|
{ statement_type(SUPPORTS); }
|
1629
|
-
bool is_hoistable() { return true; }
|
1630
1631
|
bool bubbles() { return true; }
|
1631
1632
|
ATTACH_OPERATIONS()
|
1632
1633
|
};
|
@@ -1728,12 +1729,21 @@ namespace Sass {
|
|
1728
1729
|
At_Root_Block(ParserState pstate, Block* b = 0, At_Root_Query* e = 0)
|
1729
1730
|
: Has_Block(pstate, b), expression_(e)
|
1730
1731
|
{ statement_type(ATROOT); }
|
1731
|
-
bool is_hoistable() { return true; }
|
1732
1732
|
bool bubbles() { return true; }
|
1733
1733
|
bool exclude_node(Statement* s) {
|
1734
|
+
if (expression() == 0)
|
1735
|
+
{
|
1736
|
+
return s->statement_type() == Statement::RULESET;
|
1737
|
+
}
|
1738
|
+
|
1734
1739
|
if (s->statement_type() == Statement::DIRECTIVE)
|
1735
1740
|
{
|
1736
|
-
|
1741
|
+
if (Directive* dir = dynamic_cast<Directive*>(s))
|
1742
|
+
{
|
1743
|
+
std::string keyword(dir->keyword());
|
1744
|
+
if (keyword.length() > 0) keyword.erase(0, 1);
|
1745
|
+
return expression()->exclude(keyword);
|
1746
|
+
}
|
1737
1747
|
}
|
1738
1748
|
if (s->statement_type() == Statement::MEDIA)
|
1739
1749
|
{
|
@@ -1747,9 +1757,9 @@ namespace Sass {
|
|
1747
1757
|
{
|
1748
1758
|
return expression()->exclude("supports");
|
1749
1759
|
}
|
1750
|
-
if (
|
1760
|
+
if (Directive* dir = dynamic_cast<Directive*>(s))
|
1751
1761
|
{
|
1752
|
-
return expression()->exclude("keyframes");
|
1762
|
+
if (dir->is_keyframes()) return expression()->exclude("keyframes");
|
1753
1763
|
}
|
1754
1764
|
return false;
|
1755
1765
|
}
|
@@ -1856,7 +1866,6 @@ namespace Sass {
|
|
1856
1866
|
/////////////////////////////////////////
|
1857
1867
|
class Selector : public Expression {
|
1858
1868
|
// ADD_PROPERTY(bool, has_reference)
|
1859
|
-
ADD_PROPERTY(bool, has_placeholder)
|
1860
1869
|
// line break before list separator
|
1861
1870
|
ADD_PROPERTY(bool, has_line_feed)
|
1862
1871
|
// line break after list separator
|
@@ -1871,7 +1880,6 @@ namespace Sass {
|
|
1871
1880
|
Selector(ParserState pstate, bool r = false, bool h = false)
|
1872
1881
|
: Expression(pstate),
|
1873
1882
|
// has_reference_(r),
|
1874
|
-
has_placeholder_(h),
|
1875
1883
|
has_line_feed_(false),
|
1876
1884
|
has_line_break_(false),
|
1877
1885
|
is_optional_(false),
|
@@ -1880,15 +1888,24 @@ namespace Sass {
|
|
1880
1888
|
{ concrete_type(SELECTOR); }
|
1881
1889
|
virtual ~Selector() = 0;
|
1882
1890
|
virtual size_t hash() = 0;
|
1883
|
-
virtual bool has_parent_ref() {
|
1884
|
-
return false;
|
1885
|
-
}
|
1886
1891
|
virtual unsigned long specificity() {
|
1887
|
-
return
|
1892
|
+
return 0;
|
1888
1893
|
}
|
1889
1894
|
virtual void set_media_block(Media_Block* mb) {
|
1890
1895
|
media_block(mb);
|
1891
1896
|
}
|
1897
|
+
virtual bool has_wrapped_selector() {
|
1898
|
+
return false;
|
1899
|
+
}
|
1900
|
+
virtual bool has_placeholder() {
|
1901
|
+
return false;
|
1902
|
+
}
|
1903
|
+
virtual bool has_parent_ref() {
|
1904
|
+
return false;
|
1905
|
+
}
|
1906
|
+
virtual bool has_real_parent_ref() {
|
1907
|
+
return false;
|
1908
|
+
}
|
1892
1909
|
};
|
1893
1910
|
inline Selector::~Selector() { }
|
1894
1911
|
|
@@ -1904,6 +1921,7 @@ namespace Sass {
|
|
1904
1921
|
: Selector(pstate), contents_(c), at_root_(false)
|
1905
1922
|
{ }
|
1906
1923
|
virtual bool has_parent_ref();
|
1924
|
+
virtual bool has_real_parent_ref();
|
1907
1925
|
virtual size_t hash() {
|
1908
1926
|
if (hash_ == 0) {
|
1909
1927
|
hash_combine(hash_, contents_->hash());
|
@@ -1932,6 +1950,10 @@ namespace Sass {
|
|
1932
1950
|
name_ = n.substr(pos + 1);
|
1933
1951
|
}
|
1934
1952
|
}
|
1953
|
+
virtual bool unique() const
|
1954
|
+
{
|
1955
|
+
return false;
|
1956
|
+
}
|
1935
1957
|
virtual std::string ns_name() const
|
1936
1958
|
{
|
1937
1959
|
std::string name("");
|
@@ -1976,12 +1998,13 @@ namespace Sass {
|
|
1976
1998
|
}
|
1977
1999
|
|
1978
2000
|
virtual ~Simple_Selector() = 0;
|
1979
|
-
virtual
|
2001
|
+
virtual SimpleSequence_Selector* unify_with(SimpleSequence_Selector*, Context&);
|
1980
2002
|
virtual bool has_parent_ref() { return false; };
|
2003
|
+
virtual bool has_real_parent_ref() { return false; };
|
1981
2004
|
virtual bool is_pseudo_element() { return false; }
|
1982
2005
|
virtual bool is_pseudo_class() { return false; }
|
1983
2006
|
|
1984
|
-
virtual bool is_superselector_of(
|
2007
|
+
virtual bool is_superselector_of(SimpleSequence_Selector* sub) { return false; }
|
1985
2008
|
|
1986
2009
|
bool operator==(const Simple_Selector& rhs) const;
|
1987
2010
|
inline bool operator!=(const Simple_Selector& rhs) const { return !(*this == rhs); }
|
@@ -1997,14 +2020,17 @@ namespace Sass {
|
|
1997
2020
|
// The Parent Selector Expression.
|
1998
2021
|
//////////////////////////////////
|
1999
2022
|
// parent selectors can occur in selectors but also
|
2000
|
-
// inside strings in declarations (
|
2023
|
+
// inside strings in declarations (SimpleSequence_Selector).
|
2001
2024
|
// only one simple parent selector means the first case.
|
2002
2025
|
class Parent_Selector : public Simple_Selector {
|
2026
|
+
ADD_PROPERTY(bool, real)
|
2003
2027
|
public:
|
2004
|
-
Parent_Selector(ParserState pstate)
|
2005
|
-
: Simple_Selector(pstate, "&")
|
2028
|
+
Parent_Selector(ParserState pstate, bool r = true)
|
2029
|
+
: Simple_Selector(pstate, "&"), real_(r)
|
2006
2030
|
{ /* has_reference(true); */ }
|
2031
|
+
bool is_real_parent_ref() { return real(); };
|
2007
2032
|
virtual bool has_parent_ref() { return true; };
|
2033
|
+
virtual bool has_real_parent_ref() { return is_real_parent_ref(); };
|
2008
2034
|
virtual unsigned long specificity()
|
2009
2035
|
{
|
2010
2036
|
return 0;
|
@@ -2017,50 +2043,78 @@ namespace Sass {
|
|
2017
2043
|
/////////////////////////////////////////////////////////////////////////
|
2018
2044
|
// Placeholder selectors (e.g., "%foo") for use in extend-only selectors.
|
2019
2045
|
/////////////////////////////////////////////////////////////////////////
|
2020
|
-
class
|
2046
|
+
class Placeholder_Selector : public Simple_Selector {
|
2021
2047
|
public:
|
2022
|
-
|
2048
|
+
Placeholder_Selector(ParserState pstate, std::string n)
|
2023
2049
|
: Simple_Selector(pstate, n)
|
2024
|
-
{
|
2025
|
-
|
2026
|
-
|
2050
|
+
{ }
|
2051
|
+
virtual unsigned long specificity()
|
2052
|
+
{
|
2053
|
+
return Constants::Specificity_Base;
|
2054
|
+
}
|
2055
|
+
virtual bool has_placeholder() {
|
2056
|
+
return true;
|
2057
|
+
}
|
2058
|
+
// virtual Placeholder_Selector* find_placeholder();
|
2059
|
+
virtual ~Placeholder_Selector() {};
|
2027
2060
|
ATTACH_OPERATIONS()
|
2028
2061
|
};
|
2029
2062
|
|
2030
2063
|
/////////////////////////////////////////////////////////////////////
|
2031
|
-
//
|
2064
|
+
// Element selectors (and the universal selector) -- e.g., div, span, *.
|
2032
2065
|
/////////////////////////////////////////////////////////////////////
|
2033
|
-
class
|
2066
|
+
class Element_Selector : public Simple_Selector {
|
2034
2067
|
public:
|
2035
|
-
|
2068
|
+
Element_Selector(ParserState pstate, std::string n)
|
2036
2069
|
: Simple_Selector(pstate, n)
|
2037
2070
|
{ }
|
2038
2071
|
virtual unsigned long specificity()
|
2039
2072
|
{
|
2040
|
-
|
2041
|
-
|
2042
|
-
else return Constants::Specificity_Type;
|
2073
|
+
if (name() == "*") return 0;
|
2074
|
+
else return Constants::Specificity_Element;
|
2043
2075
|
}
|
2044
2076
|
virtual Simple_Selector* unify_with(Simple_Selector*, Context&);
|
2045
|
-
virtual
|
2077
|
+
virtual SimpleSequence_Selector* unify_with(SimpleSequence_Selector*, Context&);
|
2046
2078
|
ATTACH_OPERATIONS()
|
2047
2079
|
};
|
2048
2080
|
|
2049
2081
|
////////////////////////////////////////////////
|
2050
|
-
//
|
2082
|
+
// Class selectors -- i.e., .foo.
|
2051
2083
|
////////////////////////////////////////////////
|
2052
|
-
class
|
2084
|
+
class Class_Selector : public Simple_Selector {
|
2053
2085
|
public:
|
2054
|
-
|
2086
|
+
Class_Selector(ParserState pstate, std::string n)
|
2055
2087
|
: Simple_Selector(pstate, n)
|
2056
2088
|
{ }
|
2089
|
+
virtual bool unique() const
|
2090
|
+
{
|
2091
|
+
return false;
|
2092
|
+
}
|
2093
|
+
virtual unsigned long specificity()
|
2094
|
+
{
|
2095
|
+
return Constants::Specificity_Class;
|
2096
|
+
}
|
2097
|
+
virtual SimpleSequence_Selector* unify_with(SimpleSequence_Selector*, Context&);
|
2098
|
+
ATTACH_OPERATIONS()
|
2099
|
+
};
|
2100
|
+
|
2101
|
+
////////////////////////////////////////////////
|
2102
|
+
// ID selectors -- i.e., #foo.
|
2103
|
+
////////////////////////////////////////////////
|
2104
|
+
class Id_Selector : public Simple_Selector {
|
2105
|
+
public:
|
2106
|
+
Id_Selector(ParserState pstate, std::string n)
|
2107
|
+
: Simple_Selector(pstate, n)
|
2108
|
+
{ }
|
2109
|
+
virtual bool unique() const
|
2110
|
+
{
|
2111
|
+
return true;
|
2112
|
+
}
|
2057
2113
|
virtual unsigned long specificity()
|
2058
2114
|
{
|
2059
|
-
|
2060
|
-
if (name()[0] == '.') return Constants::Specificity_Class;
|
2061
|
-
else return Constants::Specificity_Type;
|
2115
|
+
return Constants::Specificity_ID;
|
2062
2116
|
}
|
2063
|
-
virtual
|
2117
|
+
virtual SimpleSequence_Selector* unify_with(SimpleSequence_Selector*, Context&);
|
2064
2118
|
ATTACH_OPERATIONS()
|
2065
2119
|
};
|
2066
2120
|
|
@@ -2149,14 +2203,14 @@ namespace Sass {
|
|
2149
2203
|
virtual unsigned long specificity()
|
2150
2204
|
{
|
2151
2205
|
if (is_pseudo_element())
|
2152
|
-
return Constants::
|
2206
|
+
return Constants::Specificity_Element;
|
2153
2207
|
return Constants::Specificity_Pseudo;
|
2154
2208
|
}
|
2155
2209
|
bool operator==(const Simple_Selector& rhs) const;
|
2156
2210
|
bool operator==(const Pseudo_Selector& rhs) const;
|
2157
2211
|
bool operator<(const Simple_Selector& rhs) const;
|
2158
2212
|
bool operator<(const Pseudo_Selector& rhs) const;
|
2159
|
-
virtual
|
2213
|
+
virtual SimpleSequence_Selector* unify_with(SimpleSequence_Selector*, Context&);
|
2160
2214
|
ATTACH_OPERATIONS()
|
2161
2215
|
};
|
2162
2216
|
|
@@ -2169,11 +2223,6 @@ namespace Sass {
|
|
2169
2223
|
Wrapped_Selector(ParserState pstate, std::string n, Selector* sel)
|
2170
2224
|
: Simple_Selector(pstate, n), selector_(sel)
|
2171
2225
|
{ }
|
2172
|
-
virtual bool has_parent_ref() {
|
2173
|
-
// if (has_reference()) return true;
|
2174
|
-
if (!selector()) return false;
|
2175
|
-
return selector()->has_parent_ref();
|
2176
|
-
}
|
2177
2226
|
virtual bool is_superselector_of(Wrapped_Selector* sub);
|
2178
2227
|
// Selectors inside the negation pseudo-class are counted like any
|
2179
2228
|
// other, but the negation itself does not count as a pseudo-class.
|
@@ -2185,6 +2234,20 @@ namespace Sass {
|
|
2185
2234
|
}
|
2186
2235
|
return hash_;
|
2187
2236
|
}
|
2237
|
+
virtual bool has_parent_ref() {
|
2238
|
+
// if (has_reference()) return true;
|
2239
|
+
if (!selector()) return false;
|
2240
|
+
return selector()->has_parent_ref();
|
2241
|
+
}
|
2242
|
+
virtual bool has_real_parent_ref() {
|
2243
|
+
// if (has_reference()) return true;
|
2244
|
+
if (!selector()) return false;
|
2245
|
+
return selector()->has_real_parent_ref();
|
2246
|
+
}
|
2247
|
+
virtual bool has_wrapped_selector()
|
2248
|
+
{
|
2249
|
+
return true;
|
2250
|
+
}
|
2188
2251
|
virtual unsigned long specificity()
|
2189
2252
|
{
|
2190
2253
|
return selector_ ? selector_->specificity() : 0;
|
@@ -2196,16 +2259,16 @@ namespace Sass {
|
|
2196
2259
|
ATTACH_OPERATIONS()
|
2197
2260
|
};
|
2198
2261
|
|
2199
|
-
struct
|
2200
|
-
bool operator() (const
|
2262
|
+
struct Sequence_Selector_Pointer_Compare {
|
2263
|
+
bool operator() (const Sequence_Selector* const pLeft, const Sequence_Selector* const pRight) const;
|
2201
2264
|
};
|
2202
2265
|
|
2203
2266
|
////////////////////////////////////////////////////////////////////////////
|
2204
2267
|
// Simple selector sequences. Maintains flags indicating whether it contains
|
2205
2268
|
// any parent references or placeholders, to simplify expansion.
|
2206
2269
|
////////////////////////////////////////////////////////////////////////////
|
2207
|
-
typedef std::set<
|
2208
|
-
class
|
2270
|
+
typedef std::set<Sequence_Selector*, Sequence_Selector_Pointer_Compare> SourcesSet;
|
2271
|
+
class SimpleSequence_Selector : public Selector, public Vectorized<Simple_Selector*> {
|
2209
2272
|
private:
|
2210
2273
|
SourcesSet sources_;
|
2211
2274
|
ADD_PROPERTY(bool, extended);
|
@@ -2214,10 +2277,10 @@ namespace Sass {
|
|
2214
2277
|
void adjust_after_pushing(Simple_Selector* s)
|
2215
2278
|
{
|
2216
2279
|
// if (s->has_reference()) has_reference(true);
|
2217
|
-
if (s->has_placeholder()) has_placeholder(true);
|
2280
|
+
// if (s->has_placeholder()) has_placeholder(true);
|
2218
2281
|
}
|
2219
2282
|
public:
|
2220
|
-
|
2283
|
+
SimpleSequence_Selector(ParserState pstate, size_t s = 0)
|
2221
2284
|
: Selector(pstate),
|
2222
2285
|
Vectorized<Simple_Selector*>(s),
|
2223
2286
|
extended_(false),
|
@@ -2230,30 +2293,33 @@ namespace Sass {
|
|
2230
2293
|
return false;
|
2231
2294
|
};
|
2232
2295
|
|
2296
|
+
SimpleSequence_Selector& operator<<(Simple_Selector* element);
|
2297
|
+
|
2233
2298
|
bool is_universal() const
|
2234
2299
|
{
|
2235
2300
|
return length() == 1 && (*this)[0]->is_universal();
|
2236
2301
|
}
|
2237
2302
|
|
2238
|
-
|
2239
|
-
|
2240
|
-
// virtual
|
2303
|
+
Sequence_Selector* to_complex(Memory_Manager& mem);
|
2304
|
+
SimpleSequence_Selector* unify_with(SimpleSequence_Selector* rhs, Context& ctx);
|
2305
|
+
// virtual Placeholder_Selector* find_placeholder();
|
2241
2306
|
virtual bool has_parent_ref();
|
2307
|
+
virtual bool has_real_parent_ref();
|
2242
2308
|
Simple_Selector* base()
|
2243
2309
|
{
|
2244
2310
|
// Implement non-const in terms of const. Safe to const_cast since this method is non-const
|
2245
|
-
return const_cast<Simple_Selector*>(static_cast<const
|
2311
|
+
return const_cast<Simple_Selector*>(static_cast<const SimpleSequence_Selector*>(this)->base());
|
2246
2312
|
}
|
2247
2313
|
const Simple_Selector* base() const {
|
2248
2314
|
if (length() == 0) return 0;
|
2249
2315
|
// ToDo: why is this needed?
|
2250
|
-
if (dynamic_cast<
|
2316
|
+
if (dynamic_cast<Element_Selector*>((*this)[0]))
|
2251
2317
|
return (*this)[0];
|
2252
2318
|
return 0;
|
2253
2319
|
}
|
2254
|
-
virtual bool is_superselector_of(
|
2255
|
-
virtual bool is_superselector_of(
|
2256
|
-
virtual bool is_superselector_of(
|
2320
|
+
virtual bool is_superselector_of(SimpleSequence_Selector* sub, std::string wrapped = "");
|
2321
|
+
virtual bool is_superselector_of(Sequence_Selector* sub, std::string wrapped = "");
|
2322
|
+
virtual bool is_superselector_of(CommaSequence_Selector* sub, std::string wrapped = "");
|
2257
2323
|
virtual size_t hash()
|
2258
2324
|
{
|
2259
2325
|
if (Selector::hash_ == 0) {
|
@@ -2270,6 +2336,24 @@ namespace Sass {
|
|
2270
2336
|
return sum;
|
2271
2337
|
}
|
2272
2338
|
|
2339
|
+
virtual bool has_wrapped_selector()
|
2340
|
+
{
|
2341
|
+
if (length() == 0) return false;
|
2342
|
+
if (Simple_Selector* ss = elements().front()) {
|
2343
|
+
if (ss->has_wrapped_selector()) return true;
|
2344
|
+
}
|
2345
|
+
return false;
|
2346
|
+
}
|
2347
|
+
|
2348
|
+
virtual bool has_placeholder()
|
2349
|
+
{
|
2350
|
+
if (length() == 0) return false;
|
2351
|
+
if (Simple_Selector* ss = elements().front()) {
|
2352
|
+
if (ss->has_placeholder()) return true;
|
2353
|
+
}
|
2354
|
+
return false;
|
2355
|
+
}
|
2356
|
+
|
2273
2357
|
bool is_empty_reference()
|
2274
2358
|
{
|
2275
2359
|
return length() == 1 &&
|
@@ -2277,18 +2361,18 @@ namespace Sass {
|
|
2277
2361
|
}
|
2278
2362
|
std::vector<std::string> to_str_vec(); // sometimes need to convert to a flat "by-value" data structure
|
2279
2363
|
|
2280
|
-
bool operator<(const
|
2364
|
+
bool operator<(const SimpleSequence_Selector& rhs) const;
|
2281
2365
|
|
2282
|
-
bool operator==(const
|
2283
|
-
inline bool operator!=(const
|
2366
|
+
bool operator==(const SimpleSequence_Selector& rhs) const;
|
2367
|
+
inline bool operator!=(const SimpleSequence_Selector& rhs) const { return !(*this == rhs); }
|
2284
2368
|
|
2285
2369
|
SourcesSet& sources() { return sources_; }
|
2286
2370
|
void clearSources() { sources_.clear(); }
|
2287
2371
|
void mergeSources(SourcesSet& sources, Context& ctx);
|
2288
2372
|
|
2289
|
-
|
2373
|
+
SimpleSequence_Selector* clone(Context&) const; // does not clone the Simple_Selector*s
|
2290
2374
|
|
2291
|
-
|
2375
|
+
SimpleSequence_Selector* minus(SimpleSequence_Selector* rhs, Context& ctx);
|
2292
2376
|
ATTACH_OPERATIONS()
|
2293
2377
|
};
|
2294
2378
|
|
@@ -2297,13 +2381,13 @@ namespace Sass {
|
|
2297
2381
|
// CSS selector combinators (">", "+", "~", and whitespace). Essentially a
|
2298
2382
|
// linked list.
|
2299
2383
|
////////////////////////////////////////////////////////////////////////////
|
2300
|
-
class
|
2384
|
+
class Sequence_Selector : public Selector {
|
2301
2385
|
public:
|
2302
2386
|
enum Combinator { ANCESTOR_OF, PARENT_OF, PRECEDES, ADJACENT_TO, REFERENCE };
|
2303
2387
|
private:
|
2304
2388
|
ADD_PROPERTY(Combinator, combinator)
|
2305
|
-
ADD_PROPERTY(
|
2306
|
-
ADD_PROPERTY(
|
2389
|
+
ADD_PROPERTY(SimpleSequence_Selector*, head)
|
2390
|
+
ADD_PROPERTY(Sequence_Selector*, tail)
|
2307
2391
|
ADD_PROPERTY(String*, reference);
|
2308
2392
|
public:
|
2309
2393
|
bool contains_placeholder() {
|
@@ -2311,10 +2395,10 @@ namespace Sass {
|
|
2311
2395
|
if (tail() && tail()->contains_placeholder()) return true;
|
2312
2396
|
return false;
|
2313
2397
|
};
|
2314
|
-
|
2398
|
+
Sequence_Selector(ParserState pstate,
|
2315
2399
|
Combinator c = ANCESTOR_OF,
|
2316
|
-
|
2317
|
-
|
2400
|
+
SimpleSequence_Selector* h = 0,
|
2401
|
+
Sequence_Selector* t = 0,
|
2318
2402
|
String* r = 0)
|
2319
2403
|
: Selector(pstate),
|
2320
2404
|
combinator_(c),
|
@@ -2322,11 +2406,12 @@ namespace Sass {
|
|
2322
2406
|
reference_(r)
|
2323
2407
|
{
|
2324
2408
|
// if ((h && h->has_reference()) || (t && t->has_reference())) has_reference(true);
|
2325
|
-
if ((h && h->has_placeholder()) || (t && t->has_placeholder())) has_placeholder(true);
|
2409
|
+
// if ((h && h->has_placeholder()) || (t && t->has_placeholder())) has_placeholder(true);
|
2326
2410
|
}
|
2327
2411
|
virtual bool has_parent_ref();
|
2412
|
+
virtual bool has_real_parent_ref();
|
2328
2413
|
|
2329
|
-
|
2414
|
+
Sequence_Selector* skip_empty_reference()
|
2330
2415
|
{
|
2331
2416
|
if ((!head_ || !head_->length() || head_->is_empty_reference()) &&
|
2332
2417
|
combinator() == Combinator::ANCESTOR_OF)
|
@@ -2346,36 +2431,36 @@ namespace Sass {
|
|
2346
2431
|
combinator() == Combinator::ANCESTOR_OF;
|
2347
2432
|
}
|
2348
2433
|
|
2349
|
-
|
2434
|
+
Sequence_Selector* context(Context&);
|
2350
2435
|
|
2351
2436
|
|
2352
2437
|
// front returns the first real tail
|
2353
2438
|
// skips over parent and empty ones
|
2354
|
-
const
|
2439
|
+
const Sequence_Selector* first() const;
|
2355
2440
|
|
2356
2441
|
// last returns the last real tail
|
2357
|
-
const
|
2442
|
+
const Sequence_Selector* last() const;
|
2358
2443
|
|
2359
|
-
|
2444
|
+
CommaSequence_Selector* tails(Context& ctx, CommaSequence_Selector* tails);
|
2360
2445
|
|
2361
2446
|
// unconstant accessors
|
2362
|
-
|
2363
|
-
|
2447
|
+
Sequence_Selector* first();
|
2448
|
+
Sequence_Selector* last();
|
2364
2449
|
|
2365
2450
|
// some shortcuts that should be removed
|
2366
|
-
const
|
2367
|
-
|
2451
|
+
const Sequence_Selector* innermost() const { return last(); };
|
2452
|
+
Sequence_Selector* innermost() { return last(); };
|
2368
2453
|
|
2369
2454
|
size_t length() const;
|
2370
|
-
|
2371
|
-
virtual bool is_superselector_of(
|
2372
|
-
virtual bool is_superselector_of(
|
2373
|
-
virtual bool is_superselector_of(
|
2374
|
-
// virtual
|
2375
|
-
|
2455
|
+
CommaSequence_Selector* resolve_parent_refs(Context& ctx, CommaSequence_Selector* parents, bool implicit_parent = true);
|
2456
|
+
virtual bool is_superselector_of(SimpleSequence_Selector* sub, std::string wrapping = "");
|
2457
|
+
virtual bool is_superselector_of(Sequence_Selector* sub, std::string wrapping = "");
|
2458
|
+
virtual bool is_superselector_of(CommaSequence_Selector* sub, std::string wrapping = "");
|
2459
|
+
// virtual Placeholder_Selector* find_placeholder();
|
2460
|
+
CommaSequence_Selector* unify_with(Sequence_Selector* rhs, Context& ctx);
|
2376
2461
|
Combinator clear_innermost();
|
2377
|
-
void append(Context&,
|
2378
|
-
void set_innermost(
|
2462
|
+
void append(Context&, Sequence_Selector*);
|
2463
|
+
void set_innermost(Sequence_Selector*, Combinator);
|
2379
2464
|
virtual size_t hash()
|
2380
2465
|
{
|
2381
2466
|
if (hash_ == 0) {
|
@@ -2398,9 +2483,19 @@ namespace Sass {
|
|
2398
2483
|
if (tail_) tail_->set_media_block(mb);
|
2399
2484
|
if (head_) head_->set_media_block(mb);
|
2400
2485
|
}
|
2401
|
-
bool
|
2402
|
-
|
2403
|
-
|
2486
|
+
virtual bool has_wrapped_selector() {
|
2487
|
+
if (head_ && head_->has_wrapped_selector()) return true;
|
2488
|
+
if (tail_ && tail_->has_wrapped_selector()) return true;
|
2489
|
+
return false;
|
2490
|
+
}
|
2491
|
+
virtual bool has_placeholder() {
|
2492
|
+
if (head_ && head_->has_placeholder()) return true;
|
2493
|
+
if (tail_ && tail_->has_placeholder()) return true;
|
2494
|
+
return false;
|
2495
|
+
}
|
2496
|
+
bool operator<(const Sequence_Selector& rhs) const;
|
2497
|
+
bool operator==(const Sequence_Selector& rhs) const;
|
2498
|
+
inline bool operator!=(const Sequence_Selector& rhs) const { return !(*this == rhs); }
|
2404
2499
|
SourcesSet sources()
|
2405
2500
|
{
|
2406
2501
|
//s = Set.new
|
@@ -2409,8 +2504,8 @@ namespace Sass {
|
|
2409
2504
|
|
2410
2505
|
SourcesSet srcs;
|
2411
2506
|
|
2412
|
-
|
2413
|
-
|
2507
|
+
SimpleSequence_Selector* pHead = head();
|
2508
|
+
Sequence_Selector* pTail = tail();
|
2414
2509
|
|
2415
2510
|
if (pHead) {
|
2416
2511
|
SourcesSet& headSources = pHead->sources();
|
@@ -2426,9 +2521,9 @@ namespace Sass {
|
|
2426
2521
|
}
|
2427
2522
|
void addSources(SourcesSet& sources, Context& ctx) {
|
2428
2523
|
// members.map! {|m| m.is_a?(SimpleSequence) ? m.with_more_sources(sources) : m}
|
2429
|
-
|
2524
|
+
Sequence_Selector* pIter = this;
|
2430
2525
|
while (pIter) {
|
2431
|
-
|
2526
|
+
SimpleSequence_Selector* pHead = pIter->head();
|
2432
2527
|
|
2433
2528
|
if (pHead) {
|
2434
2529
|
pHead->mergeSources(sources, ctx);
|
@@ -2438,9 +2533,9 @@ namespace Sass {
|
|
2438
2533
|
}
|
2439
2534
|
}
|
2440
2535
|
void clearSources() {
|
2441
|
-
|
2536
|
+
Sequence_Selector* pIter = this;
|
2442
2537
|
while (pIter) {
|
2443
|
-
|
2538
|
+
SimpleSequence_Selector* pHead = pIter->head();
|
2444
2539
|
|
2445
2540
|
if (pHead) {
|
2446
2541
|
pHead->clearSources();
|
@@ -2449,38 +2544,39 @@ namespace Sass {
|
|
2449
2544
|
pIter = pIter->tail();
|
2450
2545
|
}
|
2451
2546
|
}
|
2452
|
-
|
2453
|
-
|
2454
|
-
// std::vector<
|
2547
|
+
Sequence_Selector* clone(Context&) const; // does not clone SimpleSequence_Selector*s
|
2548
|
+
Sequence_Selector* cloneFully(Context&) const; // clones SimpleSequence_Selector*s
|
2549
|
+
// std::vector<SimpleSequence_Selector*> to_vector();
|
2455
2550
|
ATTACH_OPERATIONS()
|
2456
2551
|
};
|
2457
2552
|
|
2458
|
-
typedef std::deque<
|
2459
|
-
typedef Subset_Map<std::string, std::pair<
|
2553
|
+
typedef std::deque<Sequence_Selector*> ComplexSelectorDeque;
|
2554
|
+
typedef Subset_Map<std::string, std::pair<Sequence_Selector*, SimpleSequence_Selector*> > ExtensionSubsetMap;
|
2460
2555
|
|
2461
2556
|
///////////////////////////////////
|
2462
2557
|
// Comma-separated selector groups.
|
2463
2558
|
///////////////////////////////////
|
2464
|
-
class
|
2559
|
+
class CommaSequence_Selector : public Selector, public Vectorized<Sequence_Selector*> {
|
2465
2560
|
ADD_PROPERTY(std::vector<std::string>, wspace)
|
2466
2561
|
protected:
|
2467
|
-
void adjust_after_pushing(
|
2562
|
+
void adjust_after_pushing(Sequence_Selector* c);
|
2468
2563
|
public:
|
2469
|
-
|
2470
|
-
: Selector(pstate), Vectorized<
|
2564
|
+
CommaSequence_Selector(ParserState pstate, size_t s = 0)
|
2565
|
+
: Selector(pstate), Vectorized<Sequence_Selector*>(s), wspace_(0)
|
2471
2566
|
{ }
|
2472
2567
|
std::string type() { return "list"; }
|
2473
2568
|
// remove parent selector references
|
2474
2569
|
// basically unwraps parsed selectors
|
2475
2570
|
virtual bool has_parent_ref();
|
2571
|
+
virtual bool has_real_parent_ref();
|
2476
2572
|
void remove_parent_selectors();
|
2477
|
-
// virtual
|
2478
|
-
|
2479
|
-
virtual bool is_superselector_of(
|
2480
|
-
virtual bool is_superselector_of(
|
2481
|
-
virtual bool is_superselector_of(
|
2482
|
-
|
2483
|
-
void populate_extends(
|
2573
|
+
// virtual Placeholder_Selector* find_placeholder();
|
2574
|
+
CommaSequence_Selector* resolve_parent_refs(Context& ctx, CommaSequence_Selector* parents, bool implicit_parent = true);
|
2575
|
+
virtual bool is_superselector_of(SimpleSequence_Selector* sub, std::string wrapping = "");
|
2576
|
+
virtual bool is_superselector_of(Sequence_Selector* sub, std::string wrapping = "");
|
2577
|
+
virtual bool is_superselector_of(CommaSequence_Selector* sub, std::string wrapping = "");
|
2578
|
+
CommaSequence_Selector* unify_with(CommaSequence_Selector*, Context&);
|
2579
|
+
void populate_extends(CommaSequence_Selector*, Context&, ExtensionSubsetMap&);
|
2484
2580
|
virtual size_t hash()
|
2485
2581
|
{
|
2486
2582
|
if (Selector::hash_ == 0) {
|
@@ -2502,14 +2598,26 @@ namespace Sass {
|
|
2502
2598
|
}
|
2503
2599
|
virtual void set_media_block(Media_Block* mb) {
|
2504
2600
|
media_block(mb);
|
2505
|
-
for (
|
2601
|
+
for (Sequence_Selector* cs : elements()) {
|
2506
2602
|
cs->set_media_block(mb);
|
2507
2603
|
}
|
2508
2604
|
}
|
2509
|
-
|
2510
|
-
|
2605
|
+
virtual bool has_wrapped_selector() {
|
2606
|
+
for (Sequence_Selector* cs : elements()) {
|
2607
|
+
if (cs->has_wrapped_selector()) return true;
|
2608
|
+
}
|
2609
|
+
return false;
|
2610
|
+
}
|
2611
|
+
virtual bool has_placeholder() {
|
2612
|
+
for (Sequence_Selector* cs : elements()) {
|
2613
|
+
if (cs->has_placeholder()) return true;
|
2614
|
+
}
|
2615
|
+
return false;
|
2616
|
+
}
|
2617
|
+
CommaSequence_Selector* clone(Context&) const; // does not clone SimpleSequence_Selector*s
|
2618
|
+
CommaSequence_Selector* cloneFully(Context&) const; // clones SimpleSequence_Selector*s
|
2511
2619
|
virtual bool operator==(const Selector& rhs) const;
|
2512
|
-
virtual bool operator==(const
|
2620
|
+
virtual bool operator==(const CommaSequence_Selector& rhs) const;
|
2513
2621
|
// Selector Lists can be compared to comma lists
|
2514
2622
|
virtual bool operator==(const Expression& rhs) const;
|
2515
2623
|
ATTACH_OPERATIONS()
|
@@ -2522,10 +2630,10 @@ namespace Sass {
|
|
2522
2630
|
// is required for proper stl collection ordering) is implemented using string comparision. This gives stable sorting
|
2523
2631
|
// behavior, and can be used to determine if the selectors would have exactly idential output. operator== matches the
|
2524
2632
|
// ruby sass implementations for eql, which sometimes perform order independent comparisions (like set comparisons of the
|
2525
|
-
// members of a SimpleSequence (
|
2633
|
+
// members of a SimpleSequence (SimpleSequence_Selector)).
|
2526
2634
|
//
|
2527
2635
|
// Due to the reliance on operator== and operater< behavior, this templated method is currently only intended for
|
2528
|
-
// use with
|
2636
|
+
// use with SimpleSequence_Selector and Sequence_Selector objects.
|
2529
2637
|
if (simpleSelectorOrderDependent) {
|
2530
2638
|
return !(one < two) && !(two < one);
|
2531
2639
|
} else {
|
@@ -2534,8 +2642,8 @@ namespace Sass {
|
|
2534
2642
|
}
|
2535
2643
|
|
2536
2644
|
// compare function for sorting and probably other other uses
|
2537
|
-
struct cmp_complex_selector { inline bool operator() (const
|
2538
|
-
struct cmp_compound_selector { inline bool operator() (const
|
2645
|
+
struct cmp_complex_selector { inline bool operator() (const Sequence_Selector* l, const Sequence_Selector* r) { return (*l < *r); } };
|
2646
|
+
struct cmp_compound_selector { inline bool operator() (const SimpleSequence_Selector* l, const SimpleSequence_Selector* r) { return (*l < *r); } };
|
2539
2647
|
struct cmp_simple_selector { inline bool operator() (const Simple_Selector* l, const Simple_Selector* r) { return (*l < *r); } };
|
2540
2648
|
|
2541
2649
|
}
|