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
@@ -3,6 +3,9 @@ There are several implementations of `libsass` for a variety of languages. Here
|
|
3
3
|
### C
|
4
4
|
* [sassc](https://github.com/hcatlin/sassc)
|
5
5
|
|
6
|
+
### Elixir
|
7
|
+
* [sass.ex](https://github.com/scottdavis/sass.ex)
|
8
|
+
|
6
9
|
### Go
|
7
10
|
* [go-libsass](https://github.com/wellington/go-libsass)
|
8
11
|
* [go_sass](https://github.com/suapapa/go_sass)
|
@@ -32,6 +35,7 @@ There are several implementations of `libsass` for a variety of languages. Here
|
|
32
35
|
|
33
36
|
### PHP
|
34
37
|
* [sassphp](https://github.com/sensational/sassphp)
|
38
|
+
* [php-sass](https://github.com/lesstif/php-sass)
|
35
39
|
|
36
40
|
### Python
|
37
41
|
* [libsass-python](https://github.com/dahlia/libsass-python)
|
@@ -63,11 +63,11 @@ enum Sass_Output_Style {
|
|
63
63
|
};
|
64
64
|
|
65
65
|
// to allocate buffer to be filled
|
66
|
-
void* sass_alloc_memory(size_t size);
|
66
|
+
ADDAPI void* ADDCALL sass_alloc_memory(size_t size);
|
67
67
|
// to allocate a buffer from existing string
|
68
|
-
char* sass_copy_c_string(const char* str);
|
68
|
+
ADDAPI char* ADDCALL sass_copy_c_string(const char* str);
|
69
69
|
// to free overtaken memory when done
|
70
|
-
void sass_free_memory(void* ptr);
|
70
|
+
ADDAPI void ADDCALL sass_free_memory(void* ptr);
|
71
71
|
|
72
72
|
// Some convenient string helper function
|
73
73
|
ADDAPI char* ADDCALL sass_string_quote (const char* str, const char quote_mark);
|
@@ -76,7 +76,8 @@ ADDAPI char* ADDCALL sass_string_unquote (const char* str);
|
|
76
76
|
// Resolve a file via the given include paths in the include char* array
|
77
77
|
ADDAPI char* ADDCALL sass_resolve_file (const char* path, const char* incs[]);
|
78
78
|
|
79
|
-
//
|
79
|
+
// Implemented sass language version
|
80
|
+
// Hardcoded version 3.4 for time being
|
80
81
|
ADDAPI const char* ADDCALL libsass_version(void);
|
81
82
|
|
82
83
|
// Get compiled libsass language
|
@@ -50,6 +50,7 @@ ADDAPI int ADDCALL sass_compiler_execute(struct Sass_Compiler* compiler);
|
|
50
50
|
// Release all memory allocated with the compiler
|
51
51
|
// This does _not_ include any contexts or options
|
52
52
|
ADDAPI void ADDCALL sass_delete_compiler(struct Sass_Compiler* compiler);
|
53
|
+
ADDAPI void ADDCALL sass_delete_options(struct Sass_Options* options);
|
53
54
|
|
54
55
|
// Release all memory allocated and also ourself
|
55
56
|
ADDAPI void ADDCALL sass_delete_file_context (struct Sass_File_Context* ctx);
|
@@ -73,6 +74,7 @@ ADDAPI enum Sass_Output_Style ADDCALL sass_option_get_output_style (struct Sass_
|
|
73
74
|
ADDAPI bool ADDCALL sass_option_get_source_comments (struct Sass_Options* options);
|
74
75
|
ADDAPI bool ADDCALL sass_option_get_source_map_embed (struct Sass_Options* options);
|
75
76
|
ADDAPI bool ADDCALL sass_option_get_source_map_contents (struct Sass_Options* options);
|
77
|
+
ADDAPI bool ADDCALL sass_option_get_source_map_file_urls (struct Sass_Options* options);
|
76
78
|
ADDAPI bool ADDCALL sass_option_get_omit_source_map_url (struct Sass_Options* options);
|
77
79
|
ADDAPI bool ADDCALL sass_option_get_is_indented_syntax_src (struct Sass_Options* options);
|
78
80
|
ADDAPI const char* ADDCALL sass_option_get_indent (struct Sass_Options* options);
|
@@ -93,6 +95,7 @@ ADDAPI void ADDCALL sass_option_set_output_style (struct Sass_Options* options,
|
|
93
95
|
ADDAPI void ADDCALL sass_option_set_source_comments (struct Sass_Options* options, bool source_comments);
|
94
96
|
ADDAPI void ADDCALL sass_option_set_source_map_embed (struct Sass_Options* options, bool source_map_embed);
|
95
97
|
ADDAPI void ADDCALL sass_option_set_source_map_contents (struct Sass_Options* options, bool source_map_contents);
|
98
|
+
ADDAPI void ADDCALL sass_option_set_source_map_file_urls (struct Sass_Options* options, bool source_map_file_urls);
|
96
99
|
ADDAPI void ADDCALL sass_option_set_omit_source_map_url (struct Sass_Options* options, bool omit_source_map_url);
|
97
100
|
ADDAPI void ADDCALL sass_option_set_is_indented_syntax_src (struct Sass_Options* options, bool is_indented_syntax_src);
|
98
101
|
ADDAPI void ADDCALL sass_option_set_indent (struct Sass_Options* options, const char* indent);
|
@@ -30,6 +30,8 @@ enum Sass_Tag {
|
|
30
30
|
enum Sass_Separator {
|
31
31
|
SASS_COMMA,
|
32
32
|
SASS_SPACE,
|
33
|
+
// only used internally to represent a hash map before evaluation
|
34
|
+
// otherwise we would be too early to check for duplicate keys
|
33
35
|
SASS_HASH
|
34
36
|
};
|
35
37
|
|
@@ -41,6 +43,32 @@ enum Sass_OP {
|
|
41
43
|
NUM_OPS // so we know how big to make the op table
|
42
44
|
};
|
43
45
|
|
46
|
+
// Creator functions for all value types
|
47
|
+
ADDAPI union Sass_Value* ADDCALL sass_make_null (void);
|
48
|
+
ADDAPI union Sass_Value* ADDCALL sass_make_boolean (bool val);
|
49
|
+
ADDAPI union Sass_Value* ADDCALL sass_make_string (const char* val);
|
50
|
+
ADDAPI union Sass_Value* ADDCALL sass_make_qstring (const char* val);
|
51
|
+
ADDAPI union Sass_Value* ADDCALL sass_make_number (double val, const char* unit);
|
52
|
+
ADDAPI union Sass_Value* ADDCALL sass_make_color (double r, double g, double b, double a);
|
53
|
+
ADDAPI union Sass_Value* ADDCALL sass_make_list (size_t len, enum Sass_Separator sep);
|
54
|
+
ADDAPI union Sass_Value* ADDCALL sass_make_map (size_t len);
|
55
|
+
ADDAPI union Sass_Value* ADDCALL sass_make_error (const char* msg);
|
56
|
+
ADDAPI union Sass_Value* ADDCALL sass_make_warning (const char* msg);
|
57
|
+
|
58
|
+
// Generic destructor function for all types
|
59
|
+
// Will release memory of all associated Sass_Values
|
60
|
+
// Means we will delete recursively for lists and maps
|
61
|
+
ADDAPI void ADDCALL sass_delete_value (union Sass_Value* val);
|
62
|
+
|
63
|
+
// Make a deep cloned copy of the given sass value
|
64
|
+
ADDAPI union Sass_Value* ADDCALL sass_clone_value (const union Sass_Value* val);
|
65
|
+
|
66
|
+
// Execute an operation for two Sass_Values and return the result as a Sass_Value too
|
67
|
+
ADDAPI union Sass_Value* ADDCALL sass_value_op (enum Sass_OP op, const union Sass_Value* a, const union Sass_Value* b);
|
68
|
+
|
69
|
+
// Stringify a Sass_Values and also return the result as a Sass_Value (of type STRING)
|
70
|
+
ADDAPI union Sass_Value* ADDCALL sass_value_stringify (const union Sass_Value* a, bool compressed, int precision);
|
71
|
+
|
44
72
|
// Return the sass tag for a generic sass value
|
45
73
|
// Check is needed before accessing specific values!
|
46
74
|
ADDAPI enum Sass_Tag ADDCALL sass_value_get_tag (const union Sass_Value* v);
|
@@ -108,33 +136,6 @@ ADDAPI void ADDCALL sass_error_set_message (union Sass_Value* v, char* msg);
|
|
108
136
|
ADDAPI char* ADDCALL sass_warning_get_message (const union Sass_Value* v);
|
109
137
|
ADDAPI void ADDCALL sass_warning_set_message (union Sass_Value* v, char* msg);
|
110
138
|
|
111
|
-
// Creator functions for all value types
|
112
|
-
ADDAPI union Sass_Value* ADDCALL sass_make_null (void);
|
113
|
-
ADDAPI union Sass_Value* ADDCALL sass_make_boolean (bool val);
|
114
|
-
ADDAPI union Sass_Value* ADDCALL sass_make_string (const char* val);
|
115
|
-
ADDAPI union Sass_Value* ADDCALL sass_make_qstring (const char* val);
|
116
|
-
ADDAPI union Sass_Value* ADDCALL sass_make_number (double val, const char* unit);
|
117
|
-
ADDAPI union Sass_Value* ADDCALL sass_make_color (double r, double g, double b, double a);
|
118
|
-
ADDAPI union Sass_Value* ADDCALL sass_make_list (size_t len, enum Sass_Separator sep);
|
119
|
-
ADDAPI union Sass_Value* ADDCALL sass_make_map (size_t len);
|
120
|
-
ADDAPI union Sass_Value* ADDCALL sass_make_error (const char* msg);
|
121
|
-
ADDAPI union Sass_Value* ADDCALL sass_make_warning (const char* msg);
|
122
|
-
|
123
|
-
// Generic destructor function for all types
|
124
|
-
// Will release memory of all associated Sass_Values
|
125
|
-
// Means we will delete recursively for lists and maps
|
126
|
-
ADDAPI void ADDCALL sass_delete_value (union Sass_Value* val);
|
127
|
-
|
128
|
-
// Make a deep cloned copy of the given sass value
|
129
|
-
ADDAPI union Sass_Value* ADDCALL sass_clone_value (const union Sass_Value* val);
|
130
|
-
|
131
|
-
// Stringify a Sass_Values and also return the result as a Sass_Value (of type STRING)
|
132
|
-
ADDAPI union Sass_Value* ADDCALL sass_value_stringify (const union Sass_Value* a, bool compressed, int precision);
|
133
|
-
|
134
|
-
// Execute an operation for two Sass_Values and return the result as a Sass_Value too
|
135
|
-
ADDAPI union Sass_Value* ADDCALL sass_value_op (enum Sass_OP op, const union Sass_Value* a, const union Sass_Value* b);
|
136
|
-
|
137
|
-
|
138
139
|
#ifdef __cplusplus
|
139
140
|
} // __cplusplus defined.
|
140
141
|
#endif
|
@@ -120,10 +120,10 @@ then
|
|
120
120
|
echo "Fetching Sass Spec PR $SPEC_PR"
|
121
121
|
git -C sass-spec fetch -u origin pull/$SPEC_PR/head:ci-spec-pr-$SPEC_PR
|
122
122
|
git -C sass-spec checkout --force ci-spec-pr-$SPEC_PR
|
123
|
-
LD_LIBRARY_PATH="$PREFIX/lib/" make $MAKE_OPTS
|
123
|
+
LD_LIBRARY_PATH="$PREFIX/lib/" make $MAKE_OPTS test_build
|
124
124
|
else
|
125
|
-
LD_LIBRARY_PATH="$PREFIX/lib/" make $MAKE_OPTS
|
125
|
+
LD_LIBRARY_PATH="$PREFIX/lib/" make $MAKE_OPTS test_build
|
126
126
|
fi
|
127
127
|
else
|
128
|
-
LD_LIBRARY_PATH="$PREFIX/lib/" make $MAKE_OPTS
|
128
|
+
LD_LIBRARY_PATH="$PREFIX/lib/" make $MAKE_OPTS test_build
|
129
129
|
fi
|
@@ -7,8 +7,17 @@ else
|
|
7
7
|
fi
|
8
8
|
|
9
9
|
if [ "x$AUTOTOOLS" == "xyes" ]; then
|
10
|
-
sudo add-apt-repository -y ppa:rbose-debianizer/automake &> /dev/null
|
11
|
-
sudo apt-get -qq update
|
12
|
-
sudo apt-get -qq install automake
|
13
10
|
AUTOTOOLS=yes
|
11
|
+
|
12
|
+
if [ "$TRAVIS_OS_NAME" == "linux" ]; then
|
13
|
+
sudo add-apt-repository -y ppa:rbose-debianizer/automake &> /dev/null
|
14
|
+
sudo apt-get -qq update
|
15
|
+
sudo apt-get -qq install automake
|
16
|
+
fi
|
17
|
+
|
18
|
+
# https://github.com/sass/libsass/pull/2183
|
19
|
+
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
|
20
|
+
brew uninstall libtool
|
21
|
+
brew install libtool
|
22
|
+
fi
|
14
23
|
fi
|
data/ext/libsass/src/ast.cpp
CHANGED
@@ -74,6 +74,21 @@ namespace Sass {
|
|
74
74
|
ltrim();
|
75
75
|
}
|
76
76
|
|
77
|
+
void Argument::set_delayed(bool delayed)
|
78
|
+
{
|
79
|
+
if (value_) value_->set_delayed(delayed);
|
80
|
+
is_delayed(delayed);
|
81
|
+
}
|
82
|
+
|
83
|
+
void Arguments::set_delayed(bool delayed)
|
84
|
+
{
|
85
|
+
for (Argument* arg : elements()) {
|
86
|
+
if (arg) arg->set_delayed(delayed);
|
87
|
+
}
|
88
|
+
is_delayed(delayed);
|
89
|
+
}
|
90
|
+
|
91
|
+
|
77
92
|
bool At_Root_Query::exclude(std::string str)
|
78
93
|
{
|
79
94
|
bool with = feature() && unquote(feature()->to_string()).compare("with") == 0;
|
@@ -107,6 +122,11 @@ namespace Sass {
|
|
107
122
|
pstate_.offset += pstate - pstate_ + pstate.offset;
|
108
123
|
}
|
109
124
|
|
125
|
+
void AST_Node::set_pstate_offset(const Offset& offset)
|
126
|
+
{
|
127
|
+
pstate_.offset = offset;
|
128
|
+
}
|
129
|
+
|
110
130
|
inline bool is_ns_eq(const std::string& l, const std::string& r)
|
111
131
|
{
|
112
132
|
if (l.empty() && r.empty()) return true;
|
@@ -117,7 +137,7 @@ namespace Sass {
|
|
117
137
|
|
118
138
|
|
119
139
|
|
120
|
-
bool
|
140
|
+
bool SimpleSequence_Selector::operator< (const SimpleSequence_Selector& rhs) const
|
121
141
|
{
|
122
142
|
size_t L = std::min(length(), rhs.length());
|
123
143
|
for (size_t i = 0; i < L; ++i)
|
@@ -134,7 +154,7 @@ namespace Sass {
|
|
134
154
|
return length() < rhs.length();
|
135
155
|
}
|
136
156
|
|
137
|
-
bool
|
157
|
+
bool SimpleSequence_Selector::has_parent_ref()
|
138
158
|
{
|
139
159
|
for (Simple_Selector* s : *this) {
|
140
160
|
if (s && s->has_parent_ref()) return true;
|
@@ -142,19 +162,33 @@ namespace Sass {
|
|
142
162
|
return false;
|
143
163
|
}
|
144
164
|
|
145
|
-
bool
|
165
|
+
bool SimpleSequence_Selector::has_real_parent_ref()
|
166
|
+
{
|
167
|
+
for (Simple_Selector* s : *this) {
|
168
|
+
if (s && s->has_real_parent_ref()) return true;
|
169
|
+
}
|
170
|
+
return false;
|
171
|
+
}
|
172
|
+
|
173
|
+
bool Sequence_Selector::has_parent_ref()
|
146
174
|
{
|
147
175
|
return (head() && head()->has_parent_ref()) ||
|
148
176
|
(tail() && tail()->has_parent_ref());
|
149
177
|
}
|
150
178
|
|
151
|
-
bool
|
179
|
+
bool Sequence_Selector::has_real_parent_ref()
|
180
|
+
{
|
181
|
+
return (head() && head()->has_real_parent_ref()) ||
|
182
|
+
(tail() && tail()->has_real_parent_ref());
|
183
|
+
}
|
184
|
+
|
185
|
+
bool Sequence_Selector::operator< (const Sequence_Selector& rhs) const
|
152
186
|
{
|
153
187
|
// const iterators for tails
|
154
|
-
const
|
155
|
-
const
|
156
|
-
|
157
|
-
|
188
|
+
const Sequence_Selector* l = this;
|
189
|
+
const Sequence_Selector* r = &rhs;
|
190
|
+
SimpleSequence_Selector* l_h = l ? l->head() : 0;
|
191
|
+
SimpleSequence_Selector* r_h = r ? r->head() : 0;
|
158
192
|
// process all tails
|
159
193
|
while (true)
|
160
194
|
{
|
@@ -210,13 +244,13 @@ namespace Sass {
|
|
210
244
|
return true;
|
211
245
|
}
|
212
246
|
|
213
|
-
bool
|
247
|
+
bool Sequence_Selector::operator== (const Sequence_Selector& rhs) const
|
214
248
|
{
|
215
249
|
// const iterators for tails
|
216
|
-
const
|
217
|
-
const
|
218
|
-
|
219
|
-
|
250
|
+
const Sequence_Selector* l = this;
|
251
|
+
const Sequence_Selector* r = &rhs;
|
252
|
+
SimpleSequence_Selector* l_h = l ? l->head() : 0;
|
253
|
+
SimpleSequence_Selector* r_h = r ? r->head() : 0;
|
220
254
|
// process all tails
|
221
255
|
while (true)
|
222
256
|
{
|
@@ -273,9 +307,9 @@ namespace Sass {
|
|
273
307
|
return false;
|
274
308
|
}
|
275
309
|
|
276
|
-
|
310
|
+
SimpleSequence_Selector* SimpleSequence_Selector::unify_with(SimpleSequence_Selector* rhs, Context& ctx)
|
277
311
|
{
|
278
|
-
|
312
|
+
SimpleSequence_Selector* unified = rhs;
|
279
313
|
for (size_t i = 0, L = length(); i < L; ++i)
|
280
314
|
{
|
281
315
|
if (!unified) break;
|
@@ -304,18 +338,18 @@ namespace Sass {
|
|
304
338
|
return ns() < rhs.ns();
|
305
339
|
}
|
306
340
|
|
307
|
-
bool
|
341
|
+
bool CommaSequence_Selector::operator== (const Selector& rhs) const
|
308
342
|
{
|
309
343
|
// solve the double dispatch problem by using RTTI information via dynamic cast
|
310
|
-
if (const
|
311
|
-
else if (const
|
312
|
-
else if (const
|
344
|
+
if (const CommaSequence_Selector* ls = dynamic_cast<const CommaSequence_Selector*>(&rhs)) { return *this == *ls; }
|
345
|
+
else if (const Sequence_Selector* ls = dynamic_cast<const Sequence_Selector*>(&rhs)) { return *this == *ls; }
|
346
|
+
else if (const SimpleSequence_Selector* ls = dynamic_cast<const SimpleSequence_Selector*>(&rhs)) { return *this == *ls; }
|
313
347
|
// no compare method
|
314
348
|
return this == &rhs;
|
315
349
|
}
|
316
350
|
|
317
351
|
// Selector lists can be compared to comma lists
|
318
|
-
bool
|
352
|
+
bool CommaSequence_Selector::operator==(const Expression& rhs) const
|
319
353
|
{
|
320
354
|
// solve the double dispatch problem by using RTTI information via dynamic cast
|
321
355
|
if (const List* ls = dynamic_cast<const List*>(&rhs)) { return *this == *ls; }
|
@@ -324,15 +358,15 @@ namespace Sass {
|
|
324
358
|
return false;
|
325
359
|
}
|
326
360
|
|
327
|
-
bool
|
361
|
+
bool CommaSequence_Selector::operator== (const CommaSequence_Selector& rhs) const
|
328
362
|
{
|
329
363
|
// for array access
|
330
364
|
size_t i = 0, n = 0;
|
331
365
|
size_t iL = length();
|
332
366
|
size_t nL = rhs.length();
|
333
367
|
// create temporary vectors and sort them
|
334
|
-
std::vector<
|
335
|
-
std::vector<
|
368
|
+
std::vector<Sequence_Selector*> l_lst = this->elements();
|
369
|
+
std::vector<Sequence_Selector*> r_lst = rhs.elements();
|
336
370
|
std::sort(l_lst.begin(), l_lst.end(), cmp_complex_selector());
|
337
371
|
std::sort(r_lst.begin(), r_lst.end(), cmp_complex_selector());
|
338
372
|
// process loop
|
@@ -342,8 +376,8 @@ namespace Sass {
|
|
342
376
|
if (i == iL) return iL == nL;
|
343
377
|
else if (n == nL) return iL == nL;
|
344
378
|
// the access the vector items
|
345
|
-
|
346
|
-
|
379
|
+
Sequence_Selector* l = l_lst[i];
|
380
|
+
Sequence_Selector* r = r_lst[n];
|
347
381
|
// skip nulls
|
348
382
|
if (!l) ++i;
|
349
383
|
else if (!r) ++n;
|
@@ -357,7 +391,7 @@ namespace Sass {
|
|
357
391
|
return true;
|
358
392
|
}
|
359
393
|
|
360
|
-
|
394
|
+
SimpleSequence_Selector* Simple_Selector::unify_with(SimpleSequence_Selector* rhs, Context& ctx)
|
361
395
|
{
|
362
396
|
for (size_t i = 0, L = rhs->length(); i < L; ++i)
|
363
397
|
{ if (to_string(ctx.c_options) == (*rhs)[i]->to_string(ctx.c_options)) return rhs; }
|
@@ -383,11 +417,11 @@ namespace Sass {
|
|
383
417
|
}
|
384
418
|
if (!found)
|
385
419
|
{
|
386
|
-
|
420
|
+
SimpleSequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, *rhs);
|
387
421
|
(*cpy) << this;
|
388
422
|
return cpy;
|
389
423
|
}
|
390
|
-
|
424
|
+
SimpleSequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, rhs->pstate());
|
391
425
|
for (size_t j = 0; j < i; ++j)
|
392
426
|
{ (*cpy) << (*rhs)[j]; }
|
393
427
|
(*cpy) << this;
|
@@ -396,7 +430,7 @@ namespace Sass {
|
|
396
430
|
return cpy;
|
397
431
|
}
|
398
432
|
|
399
|
-
Simple_Selector*
|
433
|
+
Simple_Selector* Element_Selector::unify_with(Simple_Selector* rhs, Context& ctx)
|
400
434
|
{
|
401
435
|
// check if ns can be extended
|
402
436
|
// true for no ns or universal
|
@@ -407,7 +441,7 @@ namespace Sass {
|
|
407
441
|
if (!rhs->is_universal_ns())
|
408
442
|
{
|
409
443
|
// creaty the copy inside (avoid unnecessary copies)
|
410
|
-
|
444
|
+
Element_Selector* ts = SASS_MEMORY_NEW(ctx.mem, Element_Selector, *this);
|
411
445
|
// overwrite the name if star is given as name
|
412
446
|
if (ts->name() == "*") { ts->name(rhs->name()); }
|
413
447
|
// now overwrite the namespace name and flag
|
@@ -421,7 +455,7 @@ namespace Sass {
|
|
421
455
|
if (name() == "*" && rhs->name() != "*")
|
422
456
|
{
|
423
457
|
// creaty the copy inside (avoid unnecessary copies)
|
424
|
-
|
458
|
+
Element_Selector* ts = SASS_MEMORY_NEW(ctx.mem, Element_Selector, *this);
|
425
459
|
// simply set the new name
|
426
460
|
ts->name(rhs->name());
|
427
461
|
// return copy
|
@@ -431,13 +465,13 @@ namespace Sass {
|
|
431
465
|
return this;
|
432
466
|
}
|
433
467
|
|
434
|
-
|
468
|
+
SimpleSequence_Selector* Element_Selector::unify_with(SimpleSequence_Selector* rhs, Context& ctx)
|
435
469
|
{
|
436
470
|
// TODO: handle namespaces
|
437
471
|
|
438
472
|
// if the rhs is empty, just return a copy of this
|
439
473
|
if (rhs->length() == 0) {
|
440
|
-
|
474
|
+
SimpleSequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, rhs->pstate());
|
441
475
|
(*cpy) << this;
|
442
476
|
return cpy;
|
443
477
|
}
|
@@ -446,17 +480,17 @@ namespace Sass {
|
|
446
480
|
// otherwise, this is a tag name
|
447
481
|
if (name() == "*")
|
448
482
|
{
|
449
|
-
if (typeid(*rhs_0) == typeid(
|
483
|
+
if (typeid(*rhs_0) == typeid(Element_Selector))
|
450
484
|
{
|
451
485
|
// if rhs is universal, just return this tagname + rhs's qualifiers
|
452
|
-
|
453
|
-
|
486
|
+
SimpleSequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, *rhs);
|
487
|
+
Element_Selector* ts = static_cast<Element_Selector*>(rhs_0);
|
454
488
|
(*cpy)[0] = this->unify_with(ts, ctx);
|
455
489
|
return cpy;
|
456
490
|
}
|
457
|
-
else if (dynamic_cast<
|
491
|
+
else if (dynamic_cast<Class_Selector*>(rhs_0) || dynamic_cast<Id_Selector*>(rhs_0)) {
|
458
492
|
// qualifier is `.class`, so we can prefix with `ns|*.class`
|
459
|
-
|
493
|
+
SimpleSequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, rhs->pstate());
|
460
494
|
if (has_ns() && !rhs_0->has_ns()) {
|
461
495
|
if (ns() != "*") (*cpy) << this;
|
462
496
|
}
|
@@ -469,41 +503,43 @@ namespace Sass {
|
|
469
503
|
return rhs;
|
470
504
|
}
|
471
505
|
|
472
|
-
if (typeid(*rhs_0) == typeid(
|
506
|
+
if (typeid(*rhs_0) == typeid(Element_Selector))
|
473
507
|
{
|
474
508
|
// if rhs is universal, just return this tagname + rhs's qualifiers
|
475
509
|
if (rhs_0->name() != "*" && rhs_0->ns() != "*" && rhs_0->name() != name()) return 0;
|
476
510
|
// otherwise create new compound and unify first simple selector
|
477
|
-
|
511
|
+
SimpleSequence_Selector* copy = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, *rhs);
|
478
512
|
(*copy)[0] = this->unify_with(rhs_0, ctx);
|
479
513
|
return copy;
|
480
514
|
|
481
515
|
}
|
482
516
|
// else it's a tag name and a bunch of qualifiers -- just append them
|
483
|
-
|
517
|
+
SimpleSequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, rhs->pstate());
|
484
518
|
if (name() != "*") (*cpy) << this;
|
485
519
|
(*cpy) += rhs;
|
486
520
|
return cpy;
|
487
521
|
}
|
488
522
|
|
489
|
-
|
523
|
+
SimpleSequence_Selector* Class_Selector::unify_with(SimpleSequence_Selector* rhs, Context& ctx)
|
490
524
|
{
|
491
|
-
|
525
|
+
rhs->has_line_break(has_line_break());
|
526
|
+
return Simple_Selector::unify_with(rhs, ctx);
|
527
|
+
}
|
528
|
+
|
529
|
+
SimpleSequence_Selector* Id_Selector::unify_with(SimpleSequence_Selector* rhs, Context& ctx)
|
530
|
+
{
|
531
|
+
for (size_t i = 0, L = rhs->length(); i < L; ++i)
|
492
532
|
{
|
493
|
-
|
494
|
-
{
|
495
|
-
|
496
|
-
if (typeid(*rhs_i) == typeid(Selector_Qualifier) &&
|
497
|
-
static_cast<Selector_Qualifier*>(rhs_i)->name()[0] == '#' &&
|
498
|
-
static_cast<Selector_Qualifier*>(rhs_i)->name() != name())
|
499
|
-
return 0;
|
533
|
+
Simple_Selector* rhs_i = (*rhs)[i];
|
534
|
+
if (typeid(*rhs_i) == typeid(Id_Selector) && static_cast<Id_Selector*>(rhs_i)->name() != name()) {
|
535
|
+
return 0;
|
500
536
|
}
|
501
537
|
}
|
502
538
|
rhs->has_line_break(has_line_break());
|
503
539
|
return Simple_Selector::unify_with(rhs, ctx);
|
504
540
|
}
|
505
541
|
|
506
|
-
|
542
|
+
SimpleSequence_Selector* Pseudo_Selector::unify_with(SimpleSequence_Selector* rhs, Context& ctx)
|
507
543
|
{
|
508
544
|
if (is_pseudo_element())
|
509
545
|
{
|
@@ -645,34 +681,34 @@ namespace Sass {
|
|
645
681
|
{
|
646
682
|
if (this->name() != sub->name()) return false;
|
647
683
|
if (this->name() == ":current") return false;
|
648
|
-
if (
|
649
|
-
if (
|
684
|
+
if (CommaSequence_Selector* rhs_list = dynamic_cast<CommaSequence_Selector*>(sub->selector())) {
|
685
|
+
if (CommaSequence_Selector* lhs_list = dynamic_cast<CommaSequence_Selector*>(selector())) {
|
650
686
|
return lhs_list->is_superselector_of(rhs_list);
|
651
687
|
}
|
652
|
-
error("is_superselector expected a
|
688
|
+
error("is_superselector expected a CommaSequence_Selector", sub->pstate());
|
653
689
|
} else {
|
654
|
-
error("is_superselector expected a
|
690
|
+
error("is_superselector expected a CommaSequence_Selector", sub->pstate());
|
655
691
|
}
|
656
692
|
return false;
|
657
693
|
}
|
658
694
|
|
659
|
-
bool
|
695
|
+
bool SimpleSequence_Selector::is_superselector_of(CommaSequence_Selector* rhs, std::string wrapped)
|
660
696
|
{
|
661
|
-
for (
|
697
|
+
for (Sequence_Selector* item : rhs->elements()) {
|
662
698
|
if (is_superselector_of(item, wrapped)) return true;
|
663
699
|
}
|
664
700
|
return false;
|
665
701
|
}
|
666
702
|
|
667
|
-
bool
|
703
|
+
bool SimpleSequence_Selector::is_superselector_of(Sequence_Selector* rhs, std::string wrapped)
|
668
704
|
{
|
669
705
|
if (rhs->head()) return is_superselector_of(rhs->head(), wrapped);
|
670
706
|
return false;
|
671
707
|
}
|
672
708
|
|
673
|
-
bool
|
709
|
+
bool SimpleSequence_Selector::is_superselector_of(SimpleSequence_Selector* rhs, std::string wrapping)
|
674
710
|
{
|
675
|
-
|
711
|
+
SimpleSequence_Selector* lhs = this;
|
676
712
|
Simple_Selector* lbase = lhs->base();
|
677
713
|
Simple_Selector* rbase = rhs->base();
|
678
714
|
|
@@ -719,7 +755,7 @@ namespace Sass {
|
|
719
755
|
// very special case for wrapped matches selector
|
720
756
|
if (Wrapped_Selector* wrapped = dynamic_cast<Wrapped_Selector*>(lhs)) {
|
721
757
|
if (wrapped->name() == ":not") {
|
722
|
-
if (
|
758
|
+
if (CommaSequence_Selector* not_list = dynamic_cast<CommaSequence_Selector*>(wrapped->selector())) {
|
723
759
|
if (not_list->is_superselector_of(rhs, wrapped->name())) return false;
|
724
760
|
} else {
|
725
761
|
throw std::runtime_error("wrapped not selector is not a list");
|
@@ -727,8 +763,8 @@ namespace Sass {
|
|
727
763
|
}
|
728
764
|
if (wrapped->name() == ":matches" || wrapped->name() == ":-moz-any") {
|
729
765
|
lhs = wrapped->selector();
|
730
|
-
if (
|
731
|
-
if (
|
766
|
+
if (CommaSequence_Selector* list = dynamic_cast<CommaSequence_Selector*>(wrapped->selector())) {
|
767
|
+
if (SimpleSequence_Selector* comp = dynamic_cast<SimpleSequence_Selector*>(rhs)) {
|
732
768
|
if (!wrapping.empty() && wrapping != wrapped->name()) return false;
|
733
769
|
if (wrapping.empty() || wrapping != wrapped->name()) {;
|
734
770
|
if (list->is_superselector_of(comp, wrapped->name())) return true;
|
@@ -755,7 +791,7 @@ namespace Sass {
|
|
755
791
|
auto r = (*rhs)[n];
|
756
792
|
if (Wrapped_Selector* wrapped = dynamic_cast<Wrapped_Selector*>(r)) {
|
757
793
|
if (wrapped->name() == ":not") {
|
758
|
-
if (
|
794
|
+
if (CommaSequence_Selector* ls = dynamic_cast<CommaSequence_Selector*>(wrapped->selector())) {
|
759
795
|
ls->remove_parent_selectors();
|
760
796
|
if (is_superselector_of(ls, wrapped->name())) return false;
|
761
797
|
}
|
@@ -764,7 +800,7 @@ namespace Sass {
|
|
764
800
|
if (!wrapping.empty()) {
|
765
801
|
if (wrapping != wrapped->name()) return false;
|
766
802
|
}
|
767
|
-
if (
|
803
|
+
if (CommaSequence_Selector* ls = dynamic_cast<CommaSequence_Selector*>(wrapped->selector())) {
|
768
804
|
ls->remove_parent_selectors();
|
769
805
|
return (is_superselector_of(ls, wrapped->name()));
|
770
806
|
}
|
@@ -783,22 +819,22 @@ namespace Sass {
|
|
783
819
|
}
|
784
820
|
|
785
821
|
// create complex selector (ancestor of) from compound selector
|
786
|
-
|
822
|
+
Sequence_Selector* SimpleSequence_Selector::to_complex(Memory_Manager& mem)
|
787
823
|
{
|
788
824
|
// create an intermediate complex selector
|
789
|
-
return SASS_MEMORY_NEW(mem,
|
825
|
+
return SASS_MEMORY_NEW(mem, Sequence_Selector,
|
790
826
|
pstate(),
|
791
|
-
|
827
|
+
Sequence_Selector::ANCESTOR_OF,
|
792
828
|
this,
|
793
829
|
0);
|
794
830
|
}
|
795
831
|
|
796
|
-
|
832
|
+
CommaSequence_Selector* Sequence_Selector::unify_with(Sequence_Selector* other, Context& ctx)
|
797
833
|
{
|
798
834
|
|
799
835
|
// get last tails (on the right side)
|
800
|
-
|
801
|
-
|
836
|
+
Sequence_Selector* l_last = this->last();
|
837
|
+
Sequence_Selector* r_last = other->last();
|
802
838
|
|
803
839
|
// check valid pointers (assertion)
|
804
840
|
SASS_ASSERT(l_last, "lhs is null");
|
@@ -811,15 +847,15 @@ namespace Sass {
|
|
811
847
|
if (r_last->combinator() != Combinator::ANCESTOR_OF ) return 0;
|
812
848
|
|
813
849
|
// get the headers for the last tails
|
814
|
-
|
815
|
-
|
850
|
+
SimpleSequence_Selector* l_last_head = l_last->head();
|
851
|
+
SimpleSequence_Selector* r_last_head = r_last->head();
|
816
852
|
|
817
853
|
// check valid head pointers (assertion)
|
818
854
|
SASS_ASSERT(l_last_head, "lhs head is null");
|
819
855
|
SASS_ASSERT(r_last_head, "rhs head is null");
|
820
856
|
|
821
857
|
// get the unification of the last compound selectors
|
822
|
-
|
858
|
+
SimpleSequence_Selector* unified = r_last_head->unify_with(l_last_head, ctx);
|
823
859
|
|
824
860
|
// abort if we could not unify heads
|
825
861
|
if (unified == 0) return 0;
|
@@ -843,7 +879,7 @@ namespace Sass {
|
|
843
879
|
if (!is_universal)
|
844
880
|
{
|
845
881
|
// create some temporaries to convert to node
|
846
|
-
|
882
|
+
Sequence_Selector* fake = unified->to_complex(ctx.mem);
|
847
883
|
Node unified_node = complexSelectorToNode(fake, ctx);
|
848
884
|
// add to permutate the list?
|
849
885
|
rhsNode.plus(unified_node);
|
@@ -851,7 +887,7 @@ namespace Sass {
|
|
851
887
|
|
852
888
|
// do some magic we inherit from node and extend
|
853
889
|
Node node = Extend::subweave(lhsNode, rhsNode, ctx);
|
854
|
-
|
890
|
+
CommaSequence_Selector* result = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, pstate());
|
855
891
|
NodeDequePtr col = node.collection(); // move from collection to list
|
856
892
|
for (NodeDeque::iterator it = col->begin(), end = col->end(); it != end; it++)
|
857
893
|
{ (*result) << nodeToComplexSelector(Node::naiveTrim(*it, ctx), ctx); }
|
@@ -861,7 +897,7 @@ namespace Sass {
|
|
861
897
|
|
862
898
|
}
|
863
899
|
|
864
|
-
bool
|
900
|
+
bool SimpleSequence_Selector::operator== (const SimpleSequence_Selector& rhs) const
|
865
901
|
{
|
866
902
|
// for array access
|
867
903
|
size_t i = 0, n = 0;
|
@@ -894,26 +930,26 @@ namespace Sass {
|
|
894
930
|
return true;
|
895
931
|
}
|
896
932
|
|
897
|
-
bool
|
933
|
+
bool Sequence_Selector_Pointer_Compare::operator() (const Sequence_Selector* const pLeft, const Sequence_Selector* const pRight) const {
|
898
934
|
return *pLeft < *pRight;
|
899
935
|
}
|
900
936
|
|
901
|
-
bool
|
937
|
+
bool Sequence_Selector::is_superselector_of(SimpleSequence_Selector* rhs, std::string wrapping)
|
902
938
|
{
|
903
939
|
return last()->head() && last()->head()->is_superselector_of(rhs, wrapping);
|
904
940
|
}
|
905
941
|
|
906
|
-
bool
|
942
|
+
bool Sequence_Selector::is_superselector_of(Sequence_Selector* rhs, std::string wrapping)
|
907
943
|
{
|
908
|
-
|
944
|
+
Sequence_Selector* lhs = this;
|
909
945
|
// check for selectors with leading or trailing combinators
|
910
946
|
if (!lhs->head() || !rhs->head())
|
911
947
|
{ return false; }
|
912
|
-
const
|
913
|
-
if (l_innermost->combinator() !=
|
948
|
+
const Sequence_Selector* l_innermost = lhs->innermost();
|
949
|
+
if (l_innermost->combinator() != Sequence_Selector::ANCESTOR_OF)
|
914
950
|
{ return false; }
|
915
|
-
const
|
916
|
-
if (r_innermost->combinator() !=
|
951
|
+
const Sequence_Selector* r_innermost = rhs->innermost();
|
952
|
+
if (r_innermost->combinator() != Sequence_Selector::ANCESTOR_OF)
|
917
953
|
{ return false; }
|
918
954
|
// more complex (i.e., longer) selectors are always more specific
|
919
955
|
size_t l_len = lhs->length(), r_len = rhs->length();
|
@@ -925,9 +961,9 @@ namespace Sass {
|
|
925
961
|
|
926
962
|
// we have to look one tail deeper, since we cary the
|
927
963
|
// combinator around for it (which is important here)
|
928
|
-
if (rhs->tail() && lhs->tail() && combinator() !=
|
929
|
-
|
930
|
-
|
964
|
+
if (rhs->tail() && lhs->tail() && combinator() != Sequence_Selector::ANCESTOR_OF) {
|
965
|
+
Sequence_Selector* lhs_tail = lhs->tail();
|
966
|
+
Sequence_Selector* rhs_tail = rhs->tail();
|
931
967
|
if (lhs_tail->combinator() != rhs_tail->combinator()) return false;
|
932
968
|
if (lhs_tail->head() && !rhs_tail->head()) return false;
|
933
969
|
if (!lhs_tail->head() && rhs_tail->head()) return false;
|
@@ -937,7 +973,7 @@ namespace Sass {
|
|
937
973
|
}
|
938
974
|
|
939
975
|
bool found = false;
|
940
|
-
|
976
|
+
Sequence_Selector* marker = rhs;
|
941
977
|
for (size_t i = 0, L = rhs->length(); i < L; ++i) {
|
942
978
|
if (i == L-1)
|
943
979
|
{ return false; }
|
@@ -961,17 +997,17 @@ namespace Sass {
|
|
961
997
|
else
|
962
998
|
return lhs.tail.is_superselector_of(marker.tail)
|
963
999
|
*/
|
964
|
-
if (lhs->combinator() !=
|
1000
|
+
if (lhs->combinator() != Sequence_Selector::ANCESTOR_OF)
|
965
1001
|
{
|
966
|
-
if (marker->combinator() ==
|
1002
|
+
if (marker->combinator() == Sequence_Selector::ANCESTOR_OF)
|
967
1003
|
{ return false; }
|
968
|
-
if (!(lhs->combinator() ==
|
1004
|
+
if (!(lhs->combinator() == Sequence_Selector::PRECEDES ? marker->combinator() != Sequence_Selector::PARENT_OF : lhs->combinator() == marker->combinator()))
|
969
1005
|
{ return false; }
|
970
1006
|
return lhs->tail()->is_superselector_of(marker->tail());
|
971
1007
|
}
|
972
|
-
else if (marker->combinator() !=
|
1008
|
+
else if (marker->combinator() != Sequence_Selector::ANCESTOR_OF)
|
973
1009
|
{
|
974
|
-
if (marker->combinator() !=
|
1010
|
+
if (marker->combinator() != Sequence_Selector::PARENT_OF)
|
975
1011
|
{ return false; }
|
976
1012
|
return lhs->tail()->is_superselector_of(marker->tail());
|
977
1013
|
}
|
@@ -983,18 +1019,18 @@ namespace Sass {
|
|
983
1019
|
return false;
|
984
1020
|
}
|
985
1021
|
|
986
|
-
size_t
|
1022
|
+
size_t Sequence_Selector::length() const
|
987
1023
|
{
|
988
1024
|
// TODO: make this iterative
|
989
1025
|
if (!tail()) return 1;
|
990
1026
|
return 1 + tail()->length();
|
991
1027
|
}
|
992
1028
|
|
993
|
-
|
1029
|
+
Sequence_Selector* Sequence_Selector::context(Context& ctx)
|
994
1030
|
{
|
995
1031
|
if (!tail()) return 0;
|
996
1032
|
if (!head()) return tail()->context(ctx);
|
997
|
-
|
1033
|
+
Sequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, Sequence_Selector, pstate(), combinator(), head(), tail()->context(ctx));
|
998
1034
|
cpy->media_block(media_block());
|
999
1035
|
return cpy;
|
1000
1036
|
}
|
@@ -1003,13 +1039,13 @@ namespace Sass {
|
|
1003
1039
|
// check if we need to append some headers
|
1004
1040
|
// then we need to check for the combinator
|
1005
1041
|
// only then we can safely set the new tail
|
1006
|
-
void
|
1042
|
+
void Sequence_Selector::append(Context& ctx, Sequence_Selector* ss)
|
1007
1043
|
{
|
1008
1044
|
|
1009
|
-
|
1045
|
+
Sequence_Selector* t = ss->tail();
|
1010
1046
|
Combinator c = ss->combinator();
|
1011
1047
|
String* r = ss->reference();
|
1012
|
-
|
1048
|
+
SimpleSequence_Selector* h = ss->head();
|
1013
1049
|
|
1014
1050
|
if (ss->has_line_feed()) has_line_feed(true);
|
1015
1051
|
if (ss->has_line_break()) has_line_break(true);
|
@@ -1019,23 +1055,36 @@ namespace Sass {
|
|
1019
1055
|
if (last()->combinator() != ANCESTOR_OF && c != ANCESTOR_OF) {
|
1020
1056
|
error("Invalid parent selector", pstate_);
|
1021
1057
|
} else if (last()->head_ && last()->head_->length()) {
|
1022
|
-
|
1058
|
+
SimpleSequence_Selector* rh = last()->head();
|
1023
1059
|
size_t i = 0, L = h->length();
|
1024
|
-
if (dynamic_cast<
|
1025
|
-
if (
|
1026
|
-
|
1060
|
+
if (dynamic_cast<Element_Selector*>(h->first())) {
|
1061
|
+
if (Class_Selector* sq = dynamic_cast<Class_Selector*>(rh->last())) {
|
1062
|
+
Class_Selector* sqs = SASS_MEMORY_NEW(ctx.mem, Class_Selector, *sq);
|
1027
1063
|
sqs->name(sqs->name() + (*h)[0]->name());
|
1064
|
+
sqs->pstate((*h)[0]->pstate());
|
1028
1065
|
(*rh)[rh->length()-1] = sqs;
|
1066
|
+
rh->pstate(h->pstate());
|
1029
1067
|
for (i = 1; i < L; ++i) *rh << (*h)[i];
|
1030
|
-
} else if (
|
1031
|
-
|
1068
|
+
} else if (Id_Selector* sq = dynamic_cast<Id_Selector*>(rh->last())) {
|
1069
|
+
Id_Selector* sqs = SASS_MEMORY_NEW(ctx.mem, Id_Selector, *sq);
|
1070
|
+
sqs->name(sqs->name() + (*h)[0]->name());
|
1071
|
+
sqs->pstate((*h)[0]->pstate());
|
1072
|
+
(*rh)[rh->length()-1] = sqs;
|
1073
|
+
rh->pstate(h->pstate());
|
1074
|
+
for (i = 1; i < L; ++i) *rh << (*h)[i];
|
1075
|
+
} else if (Element_Selector* ts = dynamic_cast<Element_Selector*>(rh->last())) {
|
1076
|
+
Element_Selector* tss = SASS_MEMORY_NEW(ctx.mem, Element_Selector, *ts);
|
1032
1077
|
tss->name(tss->name() + (*h)[0]->name());
|
1078
|
+
tss->pstate((*h)[0]->pstate());
|
1033
1079
|
(*rh)[rh->length()-1] = tss;
|
1080
|
+
rh->pstate(h->pstate());
|
1034
1081
|
for (i = 1; i < L; ++i) *rh << (*h)[i];
|
1035
|
-
} else if (
|
1036
|
-
|
1082
|
+
} else if (Placeholder_Selector* ps = dynamic_cast<Placeholder_Selector*>(rh->last())) {
|
1083
|
+
Placeholder_Selector* pss = SASS_MEMORY_NEW(ctx.mem, Placeholder_Selector, *ps);
|
1037
1084
|
pss->name(pss->name() + (*h)[0]->name());
|
1085
|
+
pss->pstate((*h)[0]->pstate());
|
1038
1086
|
(*rh)[rh->length()-1] = pss;
|
1087
|
+
rh->pstate(h->pstate());
|
1039
1088
|
for (i = 1; i < L; ++i) *rh << (*h)[i];
|
1040
1089
|
} else {
|
1041
1090
|
*last()->head_ += h;
|
@@ -1052,7 +1101,7 @@ namespace Sass {
|
|
1052
1101
|
|
1053
1102
|
if (last()) {
|
1054
1103
|
if (last()->combinator() != ANCESTOR_OF && c != ANCESTOR_OF) {
|
1055
|
-
|
1104
|
+
Sequence_Selector* inter = SASS_MEMORY_NEW(ctx.mem, Sequence_Selector, pstate());
|
1056
1105
|
inter->reference(r);
|
1057
1106
|
inter->combinator(c);
|
1058
1107
|
inter->tail(t);
|
@@ -1069,48 +1118,64 @@ namespace Sass {
|
|
1069
1118
|
|
1070
1119
|
}
|
1071
1120
|
|
1072
|
-
|
1121
|
+
CommaSequence_Selector* CommaSequence_Selector::resolve_parent_refs(Context& ctx, CommaSequence_Selector* ps, bool implicit_parent)
|
1073
1122
|
{
|
1074
|
-
if (!this->has_parent_ref()) return this;
|
1075
|
-
|
1123
|
+
if (!this->has_parent_ref()/* && !implicit_parent*/) return this;
|
1124
|
+
CommaSequence_Selector* ss = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, pstate());
|
1076
1125
|
for (size_t pi = 0, pL = ps->length(); pi < pL; ++pi) {
|
1077
|
-
|
1126
|
+
CommaSequence_Selector* list = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, pstate());
|
1078
1127
|
*list << (*ps)[pi];
|
1079
1128
|
for (size_t si = 0, sL = this->length(); si < sL; ++si) {
|
1080
|
-
*ss += (*this)[si]->
|
1129
|
+
*ss += (*this)[si]->resolve_parent_refs(ctx, list, implicit_parent);
|
1081
1130
|
}
|
1082
1131
|
}
|
1083
1132
|
return ss;
|
1084
1133
|
}
|
1085
1134
|
|
1086
|
-
|
1135
|
+
CommaSequence_Selector* Sequence_Selector::resolve_parent_refs(Context& ctx, CommaSequence_Selector* parents, bool implicit_parent)
|
1087
1136
|
{
|
1137
|
+
Sequence_Selector* tail = this->tail();
|
1138
|
+
SimpleSequence_Selector* head = this->head();
|
1088
1139
|
|
1089
|
-
|
1090
|
-
|
1140
|
+
if (!this->has_real_parent_ref() && !implicit_parent) {
|
1141
|
+
CommaSequence_Selector* retval = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, pstate());
|
1142
|
+
*retval << this;
|
1143
|
+
return retval;
|
1144
|
+
}
|
1091
1145
|
|
1092
|
-
// first
|
1093
|
-
|
1146
|
+
// first resolve_parent_refs the tail (which may return an expanded list)
|
1147
|
+
CommaSequence_Selector* tails = tail ? tail->resolve_parent_refs(ctx, parents, implicit_parent) : 0;
|
1094
1148
|
|
1095
1149
|
if (head && head->length() > 0) {
|
1096
1150
|
|
1097
|
-
|
1151
|
+
CommaSequence_Selector* retval = 0;
|
1098
1152
|
// we have a parent selector in a simple compound list
|
1099
1153
|
// mix parent complex selector into the compound list
|
1100
1154
|
if (dynamic_cast<Parent_Selector*>((*head)[0])) {
|
1101
|
-
retval = SASS_MEMORY_NEW(ctx.mem,
|
1155
|
+
retval = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, pstate());
|
1102
1156
|
if (parents && parents->length()) {
|
1103
1157
|
if (tails && tails->length() > 0) {
|
1104
1158
|
for (size_t n = 0, nL = tails->length(); n < nL; ++n) {
|
1105
1159
|
for (size_t i = 0, iL = parents->length(); i < iL; ++i) {
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1160
|
+
Sequence_Selector* t = (*tails)[n];
|
1161
|
+
Sequence_Selector* parent = (*parents)[i];
|
1162
|
+
Sequence_Selector* s = parent->cloneFully(ctx);
|
1163
|
+
Sequence_Selector* ss = this->clone(ctx);
|
1110
1164
|
ss->tail(t ? t->clone(ctx) : 0);
|
1111
|
-
|
1165
|
+
SimpleSequence_Selector* h = head_->clone(ctx);
|
1166
|
+
// remove parent selector from sequence
|
1112
1167
|
if (h->length()) h->erase(h->begin());
|
1113
1168
|
ss->head(h->length() ? h : 0);
|
1169
|
+
// adjust for parent selector (1 char)
|
1170
|
+
if (h->length()) {
|
1171
|
+
ParserState state((*h)[0]->pstate());
|
1172
|
+
state.offset.column += 1;
|
1173
|
+
state.column -= 1;
|
1174
|
+
(*h)[0]->pstate(state);
|
1175
|
+
}
|
1176
|
+
// keep old parser state
|
1177
|
+
s->pstate(pstate());
|
1178
|
+
// append new tail
|
1114
1179
|
s->append(ctx, ss);
|
1115
1180
|
*retval << s;
|
1116
1181
|
}
|
@@ -1120,20 +1185,31 @@ namespace Sass {
|
|
1120
1185
|
// loop above is inside out
|
1121
1186
|
else {
|
1122
1187
|
for (size_t i = 0, iL = parents->length(); i < iL; ++i) {
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1188
|
+
Sequence_Selector* parent = (*parents)[i];
|
1189
|
+
Sequence_Selector* s = parent->cloneFully(ctx);
|
1190
|
+
Sequence_Selector* ss = this->clone(ctx);
|
1126
1191
|
// this is only if valid if the parent has no trailing op
|
1127
1192
|
// otherwise we cannot append more simple selectors to head
|
1128
1193
|
if (parent->last()->combinator() != ANCESTOR_OF) {
|
1129
1194
|
throw Exception::InvalidParent(parent, ss);
|
1130
1195
|
}
|
1131
1196
|
ss->tail(tail ? tail->clone(ctx) : 0);
|
1132
|
-
|
1197
|
+
SimpleSequence_Selector* h = head_->clone(ctx);
|
1198
|
+
// remove parent selector from sequence
|
1133
1199
|
if (h->length()) h->erase(h->begin());
|
1134
1200
|
ss->head(h->length() ? h : 0);
|
1135
1201
|
// \/ IMO ruby sass bug \/
|
1136
1202
|
ss->has_line_feed(false);
|
1203
|
+
// adjust for parent selector (1 char)
|
1204
|
+
if (h->length()) {
|
1205
|
+
ParserState state((*h)[0]->pstate());
|
1206
|
+
state.offset.column += 1;
|
1207
|
+
state.column -= 1;
|
1208
|
+
(*h)[0]->pstate(state);
|
1209
|
+
}
|
1210
|
+
// keep old parser state
|
1211
|
+
s->pstate(pstate());
|
1212
|
+
// append new tail
|
1137
1213
|
s->append(ctx, ss);
|
1138
1214
|
*retval << s;
|
1139
1215
|
}
|
@@ -1143,9 +1219,9 @@ namespace Sass {
|
|
1143
1219
|
else {
|
1144
1220
|
if (tails && tails->length() > 0) {
|
1145
1221
|
for (size_t n = 0, nL = tails->length(); n < nL; ++n) {
|
1146
|
-
|
1222
|
+
Sequence_Selector* cpy = this->clone(ctx);
|
1147
1223
|
cpy->tail((*tails)[n]->cloneFully(ctx));
|
1148
|
-
cpy->head(SASS_MEMORY_NEW(ctx.mem,
|
1224
|
+
cpy->head(SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, head->pstate()));
|
1149
1225
|
for (size_t i = 1, L = this->head()->length(); i < L; ++i)
|
1150
1226
|
*cpy->head() << (*this->head())[i];
|
1151
1227
|
if (!cpy->head()->length()) cpy->head(0);
|
@@ -1154,8 +1230,8 @@ namespace Sass {
|
|
1154
1230
|
}
|
1155
1231
|
// have no parent nor tails
|
1156
1232
|
else {
|
1157
|
-
|
1158
|
-
cpy->head(SASS_MEMORY_NEW(ctx.mem,
|
1233
|
+
Sequence_Selector* cpy = this->clone(ctx);
|
1234
|
+
cpy->head(SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, head->pstate()));
|
1159
1235
|
for (size_t i = 1, L = this->head()->length(); i < L; ++i)
|
1160
1236
|
*cpy->head() << (*this->head())[i];
|
1161
1237
|
if (!cpy->head()->length()) cpy->head(0);
|
@@ -1170,8 +1246,8 @@ namespace Sass {
|
|
1170
1246
|
|
1171
1247
|
for (Simple_Selector* ss : *head) {
|
1172
1248
|
if (Wrapped_Selector* ws = dynamic_cast<Wrapped_Selector*>(ss)) {
|
1173
|
-
if (
|
1174
|
-
if (parents) ws->selector(sl->
|
1249
|
+
if (CommaSequence_Selector* sl = dynamic_cast<CommaSequence_Selector*>(ws->selector())) {
|
1250
|
+
if (parents) ws->selector(sl->resolve_parent_refs(ctx, parents, implicit_parent));
|
1175
1251
|
}
|
1176
1252
|
}
|
1177
1253
|
}
|
@@ -1188,12 +1264,12 @@ namespace Sass {
|
|
1188
1264
|
return 0;
|
1189
1265
|
}
|
1190
1266
|
|
1191
|
-
|
1267
|
+
CommaSequence_Selector* Sequence_Selector::tails(Context& ctx, CommaSequence_Selector* tails)
|
1192
1268
|
{
|
1193
|
-
|
1269
|
+
CommaSequence_Selector* rv = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, pstate_);
|
1194
1270
|
if (tails && tails->length()) {
|
1195
1271
|
for (size_t i = 0, iL = tails->length(); i < iL; ++i) {
|
1196
|
-
|
1272
|
+
Sequence_Selector* pr = this->clone(ctx);
|
1197
1273
|
pr->tail((*tails)[i]);
|
1198
1274
|
*rv << pr;
|
1199
1275
|
}
|
@@ -1205,11 +1281,11 @@ namespace Sass {
|
|
1205
1281
|
}
|
1206
1282
|
|
1207
1283
|
// return the last tail that is defined
|
1208
|
-
|
1284
|
+
Sequence_Selector* Sequence_Selector::first()
|
1209
1285
|
{
|
1210
1286
|
// declare variables used in loop
|
1211
|
-
|
1212
|
-
const
|
1287
|
+
Sequence_Selector* cur = this;
|
1288
|
+
const SimpleSequence_Selector* head;
|
1213
1289
|
// processing loop
|
1214
1290
|
while (cur)
|
1215
1291
|
{
|
@@ -1227,11 +1303,11 @@ namespace Sass {
|
|
1227
1303
|
}
|
1228
1304
|
|
1229
1305
|
// return the last tail that is defined
|
1230
|
-
const
|
1306
|
+
const Sequence_Selector* Sequence_Selector::first() const
|
1231
1307
|
{
|
1232
1308
|
// declare variables used in loop
|
1233
|
-
const
|
1234
|
-
const
|
1309
|
+
const Sequence_Selector* cur = this->tail_;
|
1310
|
+
const SimpleSequence_Selector* head = head_;
|
1235
1311
|
// processing loop
|
1236
1312
|
while (cur)
|
1237
1313
|
{
|
@@ -1251,21 +1327,21 @@ namespace Sass {
|
|
1251
1327
|
}
|
1252
1328
|
|
1253
1329
|
// return the last tail that is defined
|
1254
|
-
|
1330
|
+
Sequence_Selector* Sequence_Selector::last()
|
1255
1331
|
{
|
1256
1332
|
// ToDo: implement with a while loop
|
1257
1333
|
return tail_? tail_->last() : this;
|
1258
1334
|
}
|
1259
1335
|
|
1260
1336
|
// return the last tail that is defined
|
1261
|
-
const
|
1337
|
+
const Sequence_Selector* Sequence_Selector::last() const
|
1262
1338
|
{
|
1263
1339
|
// ToDo: implement with a while loop
|
1264
1340
|
return tail_? tail_->last() : this;
|
1265
1341
|
}
|
1266
1342
|
|
1267
1343
|
|
1268
|
-
|
1344
|
+
Sequence_Selector::Combinator Sequence_Selector::clear_innermost()
|
1269
1345
|
{
|
1270
1346
|
Combinator c;
|
1271
1347
|
if (!tail() || tail()->tail() == 0)
|
@@ -1275,7 +1351,7 @@ namespace Sass {
|
|
1275
1351
|
return c;
|
1276
1352
|
}
|
1277
1353
|
|
1278
|
-
void
|
1354
|
+
void Sequence_Selector::set_innermost(Sequence_Selector* val, Combinator c)
|
1279
1355
|
{
|
1280
1356
|
if (!tail())
|
1281
1357
|
{ tail(val); combinator(c); }
|
@@ -1283,18 +1359,18 @@ namespace Sass {
|
|
1283
1359
|
{ tail()->set_innermost(val, c); }
|
1284
1360
|
}
|
1285
1361
|
|
1286
|
-
|
1362
|
+
Sequence_Selector* Sequence_Selector::clone(Context& ctx) const
|
1287
1363
|
{
|
1288
|
-
|
1364
|
+
Sequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, Sequence_Selector, *this);
|
1289
1365
|
cpy->is_optional(this->is_optional());
|
1290
1366
|
cpy->media_block(this->media_block());
|
1291
1367
|
if (tail()) cpy->tail(tail()->clone(ctx));
|
1292
1368
|
return cpy;
|
1293
1369
|
}
|
1294
1370
|
|
1295
|
-
|
1371
|
+
Sequence_Selector* Sequence_Selector::cloneFully(Context& ctx) const
|
1296
1372
|
{
|
1297
|
-
|
1373
|
+
Sequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, Sequence_Selector, *this);
|
1298
1374
|
cpy->is_optional(this->is_optional());
|
1299
1375
|
cpy->media_block(this->media_block());
|
1300
1376
|
if (head()) {
|
@@ -1308,26 +1384,26 @@ namespace Sass {
|
|
1308
1384
|
return cpy;
|
1309
1385
|
}
|
1310
1386
|
|
1311
|
-
|
1387
|
+
SimpleSequence_Selector* SimpleSequence_Selector::clone(Context& ctx) const
|
1312
1388
|
{
|
1313
|
-
|
1389
|
+
SimpleSequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, *this);
|
1314
1390
|
cpy->is_optional(this->is_optional());
|
1315
1391
|
cpy->media_block(this->media_block());
|
1316
1392
|
cpy->extended(this->extended());
|
1317
1393
|
return cpy;
|
1318
1394
|
}
|
1319
1395
|
|
1320
|
-
|
1396
|
+
CommaSequence_Selector* CommaSequence_Selector::clone(Context& ctx) const
|
1321
1397
|
{
|
1322
|
-
|
1398
|
+
CommaSequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, *this);
|
1323
1399
|
cpy->is_optional(this->is_optional());
|
1324
1400
|
cpy->media_block(this->media_block());
|
1325
1401
|
return cpy;
|
1326
1402
|
}
|
1327
1403
|
|
1328
|
-
|
1404
|
+
CommaSequence_Selector* CommaSequence_Selector::cloneFully(Context& ctx) const
|
1329
1405
|
{
|
1330
|
-
|
1406
|
+
CommaSequence_Selector* cpy = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, pstate());
|
1331
1407
|
cpy->is_optional(this->is_optional());
|
1332
1408
|
cpy->media_block(this->media_block());
|
1333
1409
|
for (size_t i = 0, L = length(); i < L; ++i) {
|
@@ -1337,21 +1413,21 @@ namespace Sass {
|
|
1337
1413
|
}
|
1338
1414
|
|
1339
1415
|
/* not used anymore - remove?
|
1340
|
-
|
1416
|
+
Placeholder_Selector* Selector::find_placeholder()
|
1341
1417
|
{
|
1342
1418
|
return 0;
|
1343
1419
|
}*/
|
1344
1420
|
|
1345
1421
|
// remove parent selector references
|
1346
1422
|
// basically unwraps parsed selectors
|
1347
|
-
void
|
1423
|
+
void CommaSequence_Selector::remove_parent_selectors()
|
1348
1424
|
{
|
1349
1425
|
// Check every rhs selector against left hand list
|
1350
1426
|
for(size_t i = 0, L = length(); i < L; ++i) {
|
1351
1427
|
if (!(*this)[i]->head()) continue;
|
1352
1428
|
if ((*this)[i]->head()->is_empty_reference()) {
|
1353
1429
|
// simply move to the next tail if we have "no" combinator
|
1354
|
-
if ((*this)[i]->combinator() ==
|
1430
|
+
if ((*this)[i]->combinator() == Sequence_Selector::ANCESTOR_OF) {
|
1355
1431
|
if ((*this)[i]->tail() != NULL) {
|
1356
1432
|
if ((*this)[i]->has_line_feed()) {
|
1357
1433
|
(*this)[i]->tail()->has_line_feed(true);
|
@@ -1367,14 +1443,22 @@ namespace Sass {
|
|
1367
1443
|
}
|
1368
1444
|
}
|
1369
1445
|
|
1370
|
-
bool
|
1446
|
+
bool CommaSequence_Selector::has_parent_ref()
|
1371
1447
|
{
|
1372
|
-
for (
|
1448
|
+
for (Sequence_Selector* s : *this) {
|
1373
1449
|
if (s && s->has_parent_ref()) return true;
|
1374
1450
|
}
|
1375
1451
|
return false;
|
1376
1452
|
}
|
1377
1453
|
|
1454
|
+
bool CommaSequence_Selector::has_real_parent_ref()
|
1455
|
+
{
|
1456
|
+
for (Sequence_Selector* s : *this) {
|
1457
|
+
if (s && s->has_real_parent_ref()) return true;
|
1458
|
+
}
|
1459
|
+
return false;
|
1460
|
+
}
|
1461
|
+
|
1378
1462
|
bool Selector_Schema::has_parent_ref()
|
1379
1463
|
{
|
1380
1464
|
if (String_Schema* schema = dynamic_cast<String_Schema*>(contents())) {
|
@@ -1383,14 +1467,23 @@ namespace Sass {
|
|
1383
1467
|
return false;
|
1384
1468
|
}
|
1385
1469
|
|
1386
|
-
|
1470
|
+
bool Selector_Schema::has_real_parent_ref()
|
1471
|
+
{
|
1472
|
+
if (String_Schema* schema = dynamic_cast<String_Schema*>(contents())) {
|
1473
|
+
Parent_Selector* p = dynamic_cast<Parent_Selector*>(schema->at(0));
|
1474
|
+
return schema->length() > 0 && p != NULL && p->is_real_parent_ref();
|
1475
|
+
}
|
1476
|
+
return false;
|
1477
|
+
}
|
1478
|
+
|
1479
|
+
void CommaSequence_Selector::adjust_after_pushing(Sequence_Selector* c)
|
1387
1480
|
{
|
1388
1481
|
// if (c->has_reference()) has_reference(true);
|
1389
1482
|
}
|
1390
1483
|
|
1391
1484
|
// it's a superselector if every selector of the right side
|
1392
1485
|
// list is a superselector of the given left side selector
|
1393
|
-
bool
|
1486
|
+
bool Sequence_Selector::is_superselector_of(CommaSequence_Selector *sub, std::string wrapping)
|
1394
1487
|
{
|
1395
1488
|
// Check every rhs selector against left hand list
|
1396
1489
|
for(size_t i = 0, L = sub->length(); i < L; ++i) {
|
@@ -1401,7 +1494,7 @@ namespace Sass {
|
|
1401
1494
|
|
1402
1495
|
// it's a superselector if every selector of the right side
|
1403
1496
|
// list is a superselector of the given left side selector
|
1404
|
-
bool
|
1497
|
+
bool CommaSequence_Selector::is_superselector_of(CommaSequence_Selector *sub, std::string wrapping)
|
1405
1498
|
{
|
1406
1499
|
// Check every rhs selector against left hand list
|
1407
1500
|
for(size_t i = 0, L = sub->length(); i < L; ++i) {
|
@@ -1412,7 +1505,7 @@ namespace Sass {
|
|
1412
1505
|
|
1413
1506
|
// it's a superselector if every selector on the right side
|
1414
1507
|
// is a superselector of any one of the left side selectors
|
1415
|
-
bool
|
1508
|
+
bool CommaSequence_Selector::is_superselector_of(SimpleSequence_Selector *sub, std::string wrapping)
|
1416
1509
|
{
|
1417
1510
|
// Check every lhs selector against right hand
|
1418
1511
|
for(size_t i = 0, L = length(); i < L; ++i) {
|
@@ -1423,7 +1516,7 @@ namespace Sass {
|
|
1423
1516
|
|
1424
1517
|
// it's a superselector if every selector on the right side
|
1425
1518
|
// is a superselector of any one of the left side selectors
|
1426
|
-
bool
|
1519
|
+
bool CommaSequence_Selector::is_superselector_of(Sequence_Selector *sub, std::string wrapping)
|
1427
1520
|
{
|
1428
1521
|
// Check every lhs selector against right hand
|
1429
1522
|
for(size_t i = 0, L = length(); i < L; ++i) {
|
@@ -1432,15 +1525,15 @@ namespace Sass {
|
|
1432
1525
|
return false;
|
1433
1526
|
}
|
1434
1527
|
|
1435
|
-
|
1436
|
-
std::vector<
|
1528
|
+
CommaSequence_Selector* CommaSequence_Selector::unify_with(CommaSequence_Selector* rhs, Context& ctx) {
|
1529
|
+
std::vector<Sequence_Selector*> unified_complex_selectors;
|
1437
1530
|
// Unify all of children with RHS's children, storing the results in `unified_complex_selectors`
|
1438
1531
|
for (size_t lhs_i = 0, lhs_L = length(); lhs_i < lhs_L; ++lhs_i) {
|
1439
|
-
|
1532
|
+
Sequence_Selector* seq1 = (*this)[lhs_i];
|
1440
1533
|
for(size_t rhs_i = 0, rhs_L = rhs->length(); rhs_i < rhs_L; ++rhs_i) {
|
1441
|
-
|
1534
|
+
Sequence_Selector* seq2 = (*rhs)[rhs_i];
|
1442
1535
|
|
1443
|
-
|
1536
|
+
CommaSequence_Selector* result = seq1->unify_with(seq2, ctx);
|
1444
1537
|
if( result ) {
|
1445
1538
|
for(size_t i = 0, L = result->length(); i < L; ++i) {
|
1446
1539
|
unified_complex_selectors.push_back( (*result)[i] );
|
@@ -1449,27 +1542,27 @@ namespace Sass {
|
|
1449
1542
|
}
|
1450
1543
|
}
|
1451
1544
|
|
1452
|
-
// Creates the final
|
1453
|
-
|
1545
|
+
// Creates the final CommaSequence_Selector by combining all the complex selectors
|
1546
|
+
CommaSequence_Selector* final_result = SASS_MEMORY_NEW(ctx.mem, CommaSequence_Selector, pstate());
|
1454
1547
|
for (auto itr = unified_complex_selectors.begin(); itr != unified_complex_selectors.end(); ++itr) {
|
1455
1548
|
*final_result << *itr;
|
1456
1549
|
}
|
1457
1550
|
return final_result;
|
1458
1551
|
}
|
1459
1552
|
|
1460
|
-
void
|
1553
|
+
void CommaSequence_Selector::populate_extends(CommaSequence_Selector* extendee, Context& ctx, ExtensionSubsetMap& extends)
|
1461
1554
|
{
|
1462
1555
|
|
1463
|
-
|
1556
|
+
CommaSequence_Selector* extender = this;
|
1464
1557
|
for (auto complex_sel : extendee->elements()) {
|
1465
|
-
|
1558
|
+
Sequence_Selector* c = complex_sel;
|
1466
1559
|
|
1467
1560
|
|
1468
1561
|
// Ignore any parent selectors, until we find the first non Selector_Reference head
|
1469
|
-
|
1470
|
-
|
1562
|
+
SimpleSequence_Selector* compound_sel = c->head();
|
1563
|
+
Sequence_Selector* pIter = complex_sel;
|
1471
1564
|
while (pIter) {
|
1472
|
-
|
1565
|
+
SimpleSequence_Selector* pHead = pIter->head();
|
1473
1566
|
if (pHead && dynamic_cast<Parent_Selector*>(pHead->elements()[0]) == NULL) {
|
1474
1567
|
compound_sel = pHead;
|
1475
1568
|
break;
|
@@ -1490,7 +1583,7 @@ namespace Sass {
|
|
1490
1583
|
}
|
1491
1584
|
};
|
1492
1585
|
|
1493
|
-
std::vector<std::string>
|
1586
|
+
std::vector<std::string> SimpleSequence_Selector::to_str_vec()
|
1494
1587
|
{
|
1495
1588
|
std::vector<std::string> result;
|
1496
1589
|
result.reserve(length());
|
@@ -1499,9 +1592,16 @@ namespace Sass {
|
|
1499
1592
|
return result;
|
1500
1593
|
}
|
1501
1594
|
|
1502
|
-
|
1595
|
+
SimpleSequence_Selector& SimpleSequence_Selector::operator<<(Simple_Selector* element)
|
1596
|
+
{
|
1597
|
+
Vectorized<Simple_Selector*>::operator<<(element);
|
1598
|
+
pstate_.offset += element->pstate().offset;
|
1599
|
+
return *this;
|
1600
|
+
}
|
1601
|
+
|
1602
|
+
SimpleSequence_Selector* SimpleSequence_Selector::minus(SimpleSequence_Selector* rhs, Context& ctx)
|
1503
1603
|
{
|
1504
|
-
|
1604
|
+
SimpleSequence_Selector* result = SASS_MEMORY_NEW(ctx.mem, SimpleSequence_Selector, pstate());
|
1505
1605
|
// result->has_parent_reference(has_parent_reference());
|
1506
1606
|
|
1507
1607
|
// not very efficient because it needs to preserve order
|
@@ -1523,7 +1623,7 @@ namespace Sass {
|
|
1523
1623
|
return result;
|
1524
1624
|
}
|
1525
1625
|
|
1526
|
-
void
|
1626
|
+
void SimpleSequence_Selector::mergeSources(SourcesSet& sources, Context& ctx)
|
1527
1627
|
{
|
1528
1628
|
for (SourcesSet::iterator iterator = sources.begin(), endIterator = sources.end(); iterator != endIterator; ++iterator) {
|
1529
1629
|
this->sources_.insert((*iterator)->clone(ctx));
|
@@ -1594,9 +1694,10 @@ namespace Sass {
|
|
1594
1694
|
}
|
1595
1695
|
|
1596
1696
|
bool Ruleset::is_invisible() const {
|
1597
|
-
|
1598
|
-
|
1599
|
-
|
1697
|
+
if (CommaSequence_Selector* sl = dynamic_cast<CommaSequence_Selector*>(selector())) {
|
1698
|
+
for (size_t i = 0, L = sl->length(); i < L; ++i)
|
1699
|
+
if (!(*sl)[i]->has_placeholder()) return false;
|
1700
|
+
}
|
1600
1701
|
return true;
|
1601
1702
|
}
|
1602
1703
|
|
@@ -1983,6 +2084,21 @@ namespace Sass {
|
|
1983
2084
|
return false;
|
1984
2085
|
}
|
1985
2086
|
|
2087
|
+
bool Number::eq (const Expression& rhs) const
|
2088
|
+
{
|
2089
|
+
if (const Number* r = dynamic_cast<const Number*>(&rhs)) {
|
2090
|
+
size_t lhs_units = numerator_units_.size() + denominator_units_.size();
|
2091
|
+
size_t rhs_units = r->numerator_units_.size() + r->denominator_units_.size();
|
2092
|
+
if (!lhs_units && !rhs_units) {
|
2093
|
+
return std::fabs(value() - r->value()) < NUMBER_EPSILON;
|
2094
|
+
}
|
2095
|
+
return (numerator_units_ == r->numerator_units_) &&
|
2096
|
+
(denominator_units_ == r->denominator_units_) &&
|
2097
|
+
std::fabs(value() - r->value()) < NUMBER_EPSILON;
|
2098
|
+
}
|
2099
|
+
return false;
|
2100
|
+
}
|
2101
|
+
|
1986
2102
|
bool Number::operator== (const Expression& rhs) const
|
1987
2103
|
{
|
1988
2104
|
if (const Number* r = dynamic_cast<const Number*>(&rhs)) {
|
@@ -2149,29 +2265,6 @@ namespace Sass {
|
|
2149
2265
|
return is_interpolant() || (right() && right()->is_right_interpolant());
|
2150
2266
|
}
|
2151
2267
|
|
2152
|
-
// delay binary expressions in function arguments
|
2153
|
-
// https://github.com/sass/libsass/issues/1417
|
2154
|
-
bool Binary_Expression::can_delay(void) const
|
2155
|
-
{
|
2156
|
-
bool l_delay = false;
|
2157
|
-
bool r_delay = false;
|
2158
|
-
if (op().operand == Sass_OP::DIV) {
|
2159
|
-
if (Textual* tl = dynamic_cast<Textual*>(left())) {
|
2160
|
-
l_delay = tl->type() == Textual::NUMBER ||
|
2161
|
-
tl->type() == Textual::DIMENSION;
|
2162
|
-
} else {
|
2163
|
-
l_delay = dynamic_cast<Number*>(left()) != NULL;
|
2164
|
-
}
|
2165
|
-
if (Textual* tr = dynamic_cast<Textual*>(right())) {
|
2166
|
-
r_delay = tr->type() == Textual::NUMBER ||
|
2167
|
-
tr->type() == Textual::DIMENSION;
|
2168
|
-
} else {
|
2169
|
-
r_delay = dynamic_cast<Number*>(right()) != NULL;
|
2170
|
-
}
|
2171
|
-
}
|
2172
|
-
return l_delay && r_delay;
|
2173
|
-
}
|
2174
|
-
|
2175
2268
|
std::string AST_Node::to_string(Sass_Inspect_Options opt) const
|
2176
2269
|
{
|
2177
2270
|
Sass_Output_Options out(opt);
|
@@ -2213,4 +2306,20 @@ namespace Sass {
|
|
2213
2306
|
}
|
2214
2307
|
}
|
2215
2308
|
|
2309
|
+
//////////////////////////////////////////////////////////////////////////////////////////
|
2310
|
+
// Convert map to (key, value) list.
|
2311
|
+
//////////////////////////////////////////////////////////////////////////////////////////
|
2312
|
+
List* Map::to_list(Context& ctx, ParserState& pstate) {
|
2313
|
+
List* ret = SASS_MEMORY_NEW(ctx.mem, List, pstate, length(), SASS_COMMA);
|
2314
|
+
|
2315
|
+
for (auto key : keys()) {
|
2316
|
+
List* l = SASS_MEMORY_NEW(ctx.mem, List, pstate, 2);
|
2317
|
+
*l << key;
|
2318
|
+
*l << at(key);
|
2319
|
+
*ret << l;
|
2320
|
+
}
|
2321
|
+
|
2322
|
+
return ret;
|
2323
|
+
}
|
2324
|
+
|
2216
2325
|
}
|