precompiled-sassc 2.4.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 +7 -0
- data/.github/workflows/cibuildgem.yaml +67 -0
- data/.gitignore +18 -0
- data/.gitmodules +3 -0
- data/.travis.yml +16 -0
- data/CHANGELOG.md +97 -0
- data/CODE_OF_CONDUCT.md +10 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +22 -0
- data/README.md +80 -0
- data/Rakefile +51 -0
- data/ext/depend +4 -0
- data/ext/extconf.rb +92 -0
- data/ext/libsass/VERSION +1 -0
- data/ext/libsass/contrib/plugin.cpp +60 -0
- data/ext/libsass/include/sass/base.h +97 -0
- data/ext/libsass/include/sass/context.h +174 -0
- data/ext/libsass/include/sass/functions.h +139 -0
- data/ext/libsass/include/sass/values.h +145 -0
- data/ext/libsass/include/sass/version.h +12 -0
- data/ext/libsass/include/sass.h +15 -0
- data/ext/libsass/include/sass2scss.h +120 -0
- data/ext/libsass/src/MurmurHash2.hpp +91 -0
- data/ext/libsass/src/ast.cpp +953 -0
- data/ext/libsass/src/ast.hpp +1064 -0
- data/ext/libsass/src/ast2c.cpp +80 -0
- data/ext/libsass/src/ast2c.hpp +39 -0
- data/ext/libsass/src/ast_def_macros.hpp +140 -0
- data/ext/libsass/src/ast_fwd_decl.cpp +31 -0
- data/ext/libsass/src/ast_fwd_decl.hpp +274 -0
- data/ext/libsass/src/ast_helpers.hpp +292 -0
- data/ext/libsass/src/ast_sel_cmp.cpp +396 -0
- data/ext/libsass/src/ast_sel_super.cpp +539 -0
- data/ext/libsass/src/ast_sel_unify.cpp +275 -0
- data/ext/libsass/src/ast_sel_weave.cpp +616 -0
- data/ext/libsass/src/ast_selectors.cpp +1043 -0
- data/ext/libsass/src/ast_selectors.hpp +522 -0
- data/ext/libsass/src/ast_supports.cpp +114 -0
- data/ext/libsass/src/ast_supports.hpp +121 -0
- data/ext/libsass/src/ast_values.cpp +1154 -0
- data/ext/libsass/src/ast_values.hpp +498 -0
- data/ext/libsass/src/b64/cencode.h +32 -0
- data/ext/libsass/src/b64/encode.h +79 -0
- data/ext/libsass/src/backtrace.cpp +50 -0
- data/ext/libsass/src/backtrace.hpp +29 -0
- data/ext/libsass/src/base64vlq.cpp +47 -0
- data/ext/libsass/src/base64vlq.hpp +30 -0
- data/ext/libsass/src/bind.cpp +312 -0
- data/ext/libsass/src/bind.hpp +15 -0
- data/ext/libsass/src/c2ast.cpp +64 -0
- data/ext/libsass/src/c2ast.hpp +14 -0
- data/ext/libsass/src/c99func.c +54 -0
- data/ext/libsass/src/cencode.c +106 -0
- data/ext/libsass/src/check_nesting.cpp +393 -0
- data/ext/libsass/src/check_nesting.hpp +70 -0
- data/ext/libsass/src/color_maps.cpp +652 -0
- data/ext/libsass/src/color_maps.hpp +323 -0
- data/ext/libsass/src/constants.cpp +199 -0
- data/ext/libsass/src/constants.hpp +200 -0
- data/ext/libsass/src/context.cpp +863 -0
- data/ext/libsass/src/context.hpp +140 -0
- data/ext/libsass/src/cssize.cpp +521 -0
- data/ext/libsass/src/cssize.hpp +71 -0
- data/ext/libsass/src/dart_helpers.hpp +199 -0
- data/ext/libsass/src/debug.hpp +43 -0
- data/ext/libsass/src/debugger.hpp +963 -0
- data/ext/libsass/src/emitter.cpp +297 -0
- data/ext/libsass/src/emitter.hpp +101 -0
- data/ext/libsass/src/environment.cpp +260 -0
- data/ext/libsass/src/environment.hpp +124 -0
- data/ext/libsass/src/error_handling.cpp +233 -0
- data/ext/libsass/src/error_handling.hpp +239 -0
- data/ext/libsass/src/eval.cpp +1543 -0
- data/ext/libsass/src/eval.hpp +110 -0
- data/ext/libsass/src/eval_selectors.cpp +75 -0
- data/ext/libsass/src/expand.cpp +875 -0
- data/ext/libsass/src/expand.hpp +98 -0
- data/ext/libsass/src/extender.cpp +1188 -0
- data/ext/libsass/src/extender.hpp +399 -0
- data/ext/libsass/src/extension.cpp +43 -0
- data/ext/libsass/src/extension.hpp +89 -0
- data/ext/libsass/src/file.cpp +531 -0
- data/ext/libsass/src/file.hpp +124 -0
- data/ext/libsass/src/fn_colors.cpp +596 -0
- data/ext/libsass/src/fn_colors.hpp +85 -0
- data/ext/libsass/src/fn_lists.cpp +285 -0
- data/ext/libsass/src/fn_lists.hpp +34 -0
- data/ext/libsass/src/fn_maps.cpp +94 -0
- data/ext/libsass/src/fn_maps.hpp +30 -0
- data/ext/libsass/src/fn_miscs.cpp +244 -0
- data/ext/libsass/src/fn_miscs.hpp +40 -0
- data/ext/libsass/src/fn_numbers.cpp +227 -0
- data/ext/libsass/src/fn_numbers.hpp +45 -0
- data/ext/libsass/src/fn_selectors.cpp +205 -0
- data/ext/libsass/src/fn_selectors.hpp +35 -0
- data/ext/libsass/src/fn_strings.cpp +268 -0
- data/ext/libsass/src/fn_strings.hpp +34 -0
- data/ext/libsass/src/fn_utils.cpp +158 -0
- data/ext/libsass/src/fn_utils.hpp +62 -0
- data/ext/libsass/src/inspect.cpp +1125 -0
- data/ext/libsass/src/inspect.hpp +101 -0
- data/ext/libsass/src/json.cpp +1436 -0
- data/ext/libsass/src/json.hpp +117 -0
- data/ext/libsass/src/kwd_arg_macros.hpp +28 -0
- data/ext/libsass/src/lexer.cpp +122 -0
- data/ext/libsass/src/lexer.hpp +304 -0
- data/ext/libsass/src/listize.cpp +70 -0
- data/ext/libsass/src/listize.hpp +37 -0
- data/ext/libsass/src/mapping.hpp +19 -0
- data/ext/libsass/src/memory/allocator.cpp +48 -0
- data/ext/libsass/src/memory/allocator.hpp +138 -0
- data/ext/libsass/src/memory/config.hpp +20 -0
- data/ext/libsass/src/memory/memory_pool.hpp +186 -0
- data/ext/libsass/src/memory/shared_ptr.cpp +33 -0
- data/ext/libsass/src/memory/shared_ptr.hpp +332 -0
- data/ext/libsass/src/memory.hpp +12 -0
- data/ext/libsass/src/operation.hpp +223 -0
- data/ext/libsass/src/operators.cpp +267 -0
- data/ext/libsass/src/operators.hpp +30 -0
- data/ext/libsass/src/ordered_map.hpp +112 -0
- data/ext/libsass/src/output.cpp +320 -0
- data/ext/libsass/src/output.hpp +47 -0
- data/ext/libsass/src/parser.cpp +2965 -0
- data/ext/libsass/src/parser.hpp +394 -0
- data/ext/libsass/src/parser_selectors.cpp +189 -0
- data/ext/libsass/src/permutate.hpp +164 -0
- data/ext/libsass/src/plugins.cpp +188 -0
- data/ext/libsass/src/plugins.hpp +57 -0
- data/ext/libsass/src/position.cpp +165 -0
- data/ext/libsass/src/position.hpp +147 -0
- data/ext/libsass/src/prelexer.cpp +1780 -0
- data/ext/libsass/src/prelexer.hpp +484 -0
- data/ext/libsass/src/remove_placeholders.cpp +86 -0
- data/ext/libsass/src/remove_placeholders.hpp +37 -0
- data/ext/libsass/src/sass.cpp +156 -0
- data/ext/libsass/src/sass.hpp +147 -0
- data/ext/libsass/src/sass2scss.cpp +895 -0
- data/ext/libsass/src/sass_context.cpp +741 -0
- data/ext/libsass/src/sass_context.hpp +129 -0
- data/ext/libsass/src/sass_functions.cpp +210 -0
- data/ext/libsass/src/sass_functions.hpp +50 -0
- data/ext/libsass/src/sass_values.cpp +362 -0
- data/ext/libsass/src/sass_values.hpp +82 -0
- data/ext/libsass/src/settings.hpp +19 -0
- data/ext/libsass/src/source.cpp +69 -0
- data/ext/libsass/src/source.hpp +95 -0
- data/ext/libsass/src/source_data.hpp +32 -0
- data/ext/libsass/src/source_map.cpp +202 -0
- data/ext/libsass/src/source_map.hpp +65 -0
- data/ext/libsass/src/stylesheet.cpp +22 -0
- data/ext/libsass/src/stylesheet.hpp +57 -0
- data/ext/libsass/src/to_value.cpp +114 -0
- data/ext/libsass/src/to_value.hpp +46 -0
- data/ext/libsass/src/units.cpp +507 -0
- data/ext/libsass/src/units.hpp +110 -0
- data/ext/libsass/src/utf8/checked.h +336 -0
- data/ext/libsass/src/utf8/core.h +332 -0
- data/ext/libsass/src/utf8/unchecked.h +235 -0
- data/ext/libsass/src/utf8.h +34 -0
- data/ext/libsass/src/utf8_string.cpp +104 -0
- data/ext/libsass/src/utf8_string.hpp +38 -0
- data/ext/libsass/src/util.cpp +723 -0
- data/ext/libsass/src/util.hpp +105 -0
- data/ext/libsass/src/util_string.cpp +125 -0
- data/ext/libsass/src/util_string.hpp +73 -0
- data/ext/libsass/src/values.cpp +140 -0
- data/ext/libsass/src/values.hpp +12 -0
- data/lib/sassc/dependency.rb +17 -0
- data/lib/sassc/engine.rb +141 -0
- data/lib/sassc/error.rb +37 -0
- data/lib/sassc/functions_handler.rb +73 -0
- data/lib/sassc/import_handler.rb +50 -0
- data/lib/sassc/importer.rb +31 -0
- data/lib/sassc/native/native_context_api.rb +147 -0
- data/lib/sassc/native/native_functions_api.rb +159 -0
- data/lib/sassc/native/sass2scss_api.rb +10 -0
- data/lib/sassc/native/sass_input_style.rb +13 -0
- data/lib/sassc/native/sass_output_style.rb +12 -0
- data/lib/sassc/native/sass_value.rb +97 -0
- data/lib/sassc/native/string_list.rb +10 -0
- data/lib/sassc/native.rb +65 -0
- data/lib/sassc/sass_2_scss.rb +9 -0
- data/lib/sassc/script/functions.rb +8 -0
- data/lib/sassc/script/value/bool.rb +32 -0
- data/lib/sassc/script/value/color.rb +95 -0
- data/lib/sassc/script/value/list.rb +136 -0
- data/lib/sassc/script/value/map.rb +69 -0
- data/lib/sassc/script/value/number.rb +389 -0
- data/lib/sassc/script/value/string.rb +96 -0
- data/lib/sassc/script/value.rb +137 -0
- data/lib/sassc/script/value_conversion/base.rb +13 -0
- data/lib/sassc/script/value_conversion/bool.rb +13 -0
- data/lib/sassc/script/value_conversion/color.rb +18 -0
- data/lib/sassc/script/value_conversion/list.rb +25 -0
- data/lib/sassc/script/value_conversion/map.rb +21 -0
- data/lib/sassc/script/value_conversion/number.rb +13 -0
- data/lib/sassc/script/value_conversion/string.rb +17 -0
- data/lib/sassc/script/value_conversion.rb +69 -0
- data/lib/sassc/script.rb +17 -0
- data/lib/sassc/util/normalized_map.rb +117 -0
- data/lib/sassc/util.rb +231 -0
- data/lib/sassc/version.rb +5 -0
- data/lib/sassc.rb +57 -0
- data/sassc.gemspec +69 -0
- data/test/custom_importer_test.rb +127 -0
- data/test/engine_test.rb +314 -0
- data/test/error_test.rb +29 -0
- data/test/fixtures/paths.scss +10 -0
- data/test/functions_test.rb +340 -0
- data/test/native_test.rb +213 -0
- data/test/output_style_test.rb +107 -0
- data/test/sass_2_scss_test.rb +14 -0
- data/test/test_helper.rb +45 -0
- metadata +391 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
#ifndef SASS_AST_HELPERS_H
|
|
2
|
+
#define SASS_AST_HELPERS_H
|
|
3
|
+
|
|
4
|
+
// sass.hpp must go before all system headers to get the
|
|
5
|
+
// __EXTENSIONS__ fix on Solaris.
|
|
6
|
+
#include "sass.hpp"
|
|
7
|
+
#include <algorithm>
|
|
8
|
+
#include <functional>
|
|
9
|
+
#include "util_string.hpp"
|
|
10
|
+
|
|
11
|
+
namespace Sass {
|
|
12
|
+
|
|
13
|
+
// ###########################################################################
|
|
14
|
+
// ###########################################################################
|
|
15
|
+
|
|
16
|
+
// easier to search with name
|
|
17
|
+
const bool DELAYED = true;
|
|
18
|
+
|
|
19
|
+
// ToDo: should this really be hardcoded
|
|
20
|
+
// Note: most methods follow precision option
|
|
21
|
+
const double NUMBER_EPSILON = 1e-12;
|
|
22
|
+
|
|
23
|
+
// macro to test if numbers are equal within a small error margin
|
|
24
|
+
#define NEAR_EQUAL(lhs, rhs) std::fabs(lhs - rhs) < NUMBER_EPSILON
|
|
25
|
+
|
|
26
|
+
// ###########################################################################
|
|
27
|
+
// We define various functions and functors here.
|
|
28
|
+
// Functions satisfy the BinaryPredicate requirement
|
|
29
|
+
// Functors are structs used for e.g. unordered_map
|
|
30
|
+
// ###########################################################################
|
|
31
|
+
|
|
32
|
+
// ###########################################################################
|
|
33
|
+
// Implement compare and hashing operations for raw pointers
|
|
34
|
+
// ###########################################################################
|
|
35
|
+
|
|
36
|
+
template <class T>
|
|
37
|
+
size_t PtrHashFn(const T* ptr) {
|
|
38
|
+
return std::hash<std::size_t>()((size_t)ptr);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
struct PtrHash {
|
|
42
|
+
template <class T>
|
|
43
|
+
size_t operator() (const T* ptr) const {
|
|
44
|
+
return PtrHashFn(ptr);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
template <class T>
|
|
49
|
+
bool PtrEqualityFn(const T* lhs, const T* rhs) {
|
|
50
|
+
return lhs == rhs; // compare raw pointers
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
struct PtrEquality {
|
|
54
|
+
template <class T>
|
|
55
|
+
bool operator() (const T* lhs, const T* rhs) const {
|
|
56
|
+
return PtrEqualityFn<T>(lhs, rhs);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// ###########################################################################
|
|
61
|
+
// Implement compare and hashing operations for AST Nodes
|
|
62
|
+
// ###########################################################################
|
|
63
|
+
|
|
64
|
+
// TODO: get rid of funtions and use ObjEquality<T>
|
|
65
|
+
|
|
66
|
+
template <class T>
|
|
67
|
+
// Hash the raw pointer instead of object
|
|
68
|
+
size_t ObjPtrHashFn(const T& obj) {
|
|
69
|
+
return PtrHashFn(obj.ptr());
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
struct ObjPtrHash {
|
|
73
|
+
template <class T>
|
|
74
|
+
// Hash the raw pointer instead of object
|
|
75
|
+
size_t operator() (const T& obj) const {
|
|
76
|
+
return ObjPtrHashFn(obj);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
template <class T>
|
|
81
|
+
// Hash the object and its content
|
|
82
|
+
size_t ObjHashFn(const T& obj) {
|
|
83
|
+
return obj ? obj->hash() : 0;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
struct ObjHash {
|
|
87
|
+
template <class T>
|
|
88
|
+
// Hash the object and its content
|
|
89
|
+
size_t operator() (const T& obj) const {
|
|
90
|
+
return ObjHashFn(obj);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
template <class T>
|
|
95
|
+
// Hash the object behind pointer
|
|
96
|
+
size_t PtrObjHashFn(const T* obj) {
|
|
97
|
+
return obj ? obj->hash() : 0;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
struct PtrObjHash {
|
|
101
|
+
template <class T>
|
|
102
|
+
// Hash the object behind pointer
|
|
103
|
+
size_t operator() (const T* obj) const {
|
|
104
|
+
return PtrObjHashFn(obj);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
template <class T>
|
|
109
|
+
// Compare raw pointers to the object
|
|
110
|
+
bool ObjPtrEqualityFn(const T& lhs, const T& rhs) {
|
|
111
|
+
return PtrEqualityFn(lhs.ptr(), rhs.ptr());
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
struct ObjPtrEquality {
|
|
115
|
+
template <class T>
|
|
116
|
+
// Compare raw pointers to the object
|
|
117
|
+
bool operator() (const T& lhs, const T& rhs) const {
|
|
118
|
+
return ObjPtrEqualityFn<T>(lhs, rhs);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
template <class T>
|
|
123
|
+
// Compare the objects behind the pointers
|
|
124
|
+
bool PtrObjEqualityFn(const T* lhs, const T* rhs) {
|
|
125
|
+
if (lhs == nullptr) return rhs == nullptr;
|
|
126
|
+
else if (rhs == nullptr) return false;
|
|
127
|
+
else return *lhs == *rhs;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
struct PtrObjEquality {
|
|
131
|
+
template <class T>
|
|
132
|
+
// Compare the objects behind the pointers
|
|
133
|
+
bool operator() (const T* lhs, const T* rhs) const {
|
|
134
|
+
return PtrObjEqualityFn<T>(lhs, rhs);
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
template <class T>
|
|
139
|
+
// Compare the objects and its contents
|
|
140
|
+
bool ObjEqualityFn(const T& lhs, const T& rhs) {
|
|
141
|
+
return PtrObjEqualityFn(lhs.ptr(), rhs.ptr());
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
struct ObjEquality {
|
|
145
|
+
template <class T>
|
|
146
|
+
// Compare the objects and its contents
|
|
147
|
+
bool operator() (const T& lhs, const T& rhs) const {
|
|
148
|
+
return ObjEqualityFn<T>(lhs, rhs);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
// ###########################################################################
|
|
153
|
+
// Implement ordering operations for AST Nodes
|
|
154
|
+
// ###########################################################################
|
|
155
|
+
|
|
156
|
+
template <class T>
|
|
157
|
+
// Compare the objects behind pointers
|
|
158
|
+
bool PtrObjLessThanFn(const T* lhs, const T* rhs) {
|
|
159
|
+
if (lhs == nullptr) return rhs != nullptr;
|
|
160
|
+
else if (rhs == nullptr) return false;
|
|
161
|
+
else return *lhs < *rhs;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
struct PtrObjLessThan {
|
|
165
|
+
template <class T>
|
|
166
|
+
// Compare the objects behind pointers
|
|
167
|
+
bool operator() (const T* lhs, const T* rhs) const {
|
|
168
|
+
return PtrObjLessThanFn<T>(lhs, rhs);
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
template <class T>
|
|
173
|
+
// Compare the objects and its content
|
|
174
|
+
bool ObjLessThanFn(const T& lhs, const T& rhs) {
|
|
175
|
+
return PtrObjLessThanFn(lhs.ptr(), rhs.ptr());
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
struct ObjLessThan {
|
|
179
|
+
template <class T>
|
|
180
|
+
// Compare the objects and its content
|
|
181
|
+
bool operator() (const T& lhs, const T& rhs) const {
|
|
182
|
+
return ObjLessThanFn<T>(lhs, rhs);
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
// ###########################################################################
|
|
187
|
+
// Some STL helper functions
|
|
188
|
+
// ###########################################################################
|
|
189
|
+
|
|
190
|
+
// Check if all elements are equal
|
|
191
|
+
template <class X, class Y,
|
|
192
|
+
typename XT = typename X::value_type,
|
|
193
|
+
typename YT = typename Y::value_type>
|
|
194
|
+
bool ListEquality(const X& lhs, const Y& rhs,
|
|
195
|
+
bool(*cmp)(const XT*, const YT*))
|
|
196
|
+
{
|
|
197
|
+
return lhs.size() == rhs.size() &&
|
|
198
|
+
std::equal(lhs.begin(), lhs.end(),
|
|
199
|
+
rhs.begin(), cmp);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Return if Vector is empty
|
|
203
|
+
template <class T>
|
|
204
|
+
bool listIsEmpty(T* cnt) {
|
|
205
|
+
return cnt && cnt->empty();
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Erase items from vector that match predicate
|
|
209
|
+
template<class T, class UnaryPredicate>
|
|
210
|
+
void listEraseItemIf(T& vec, UnaryPredicate* predicate)
|
|
211
|
+
{
|
|
212
|
+
vec.erase(std::remove_if(vec.begin(), vec.end(), predicate), vec.end());
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Check that every item in `lhs` is also in `rhs`
|
|
216
|
+
// Note: this works by comparing the raw pointers
|
|
217
|
+
template <typename T>
|
|
218
|
+
bool listIsSubsetOrEqual(const T& lhs, const T& rhs) {
|
|
219
|
+
for (const auto& item : lhs) {
|
|
220
|
+
if (std::find(rhs.begin(), rhs.end(), item) == rhs.end())
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// ##########################################################################
|
|
227
|
+
// Returns whether [name] is the name of a pseudo-element
|
|
228
|
+
// that can be written with pseudo-class syntax (CSS2 vs CSS3):
|
|
229
|
+
// `:before`, `:after`, `:first-line`, or `:first-letter`
|
|
230
|
+
// ##########################################################################
|
|
231
|
+
inline bool isFakePseudoElement(const sass::string& name)
|
|
232
|
+
{
|
|
233
|
+
return Util::equalsLiteral("after", name)
|
|
234
|
+
|| Util::equalsLiteral("before", name)
|
|
235
|
+
|| Util::equalsLiteral("first-line", name)
|
|
236
|
+
|| Util::equalsLiteral("first-letter", name);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// ##########################################################################
|
|
240
|
+
// Names of pseudo selectors that take selectors as arguments,
|
|
241
|
+
// and that are subselectors of their arguments.
|
|
242
|
+
// For example, `.foo` is a superselector of `:matches(.foo)`.
|
|
243
|
+
// ##########################################################################
|
|
244
|
+
inline bool isSubselectorPseudo(const sass::string& norm)
|
|
245
|
+
{
|
|
246
|
+
return Util::equalsLiteral("any", norm)
|
|
247
|
+
|| Util::equalsLiteral("matches", norm)
|
|
248
|
+
|| Util::equalsLiteral("nth-child", norm)
|
|
249
|
+
|| Util::equalsLiteral("nth-last-child", norm);
|
|
250
|
+
}
|
|
251
|
+
// EO isSubselectorPseudo
|
|
252
|
+
|
|
253
|
+
// ###########################################################################
|
|
254
|
+
// Pseudo-class selectors that take unadorned selectors as arguments.
|
|
255
|
+
// ###########################################################################
|
|
256
|
+
inline bool isSelectorPseudoClass(const sass::string& test)
|
|
257
|
+
{
|
|
258
|
+
return Util::equalsLiteral("not", test)
|
|
259
|
+
|| Util::equalsLiteral("matches", test)
|
|
260
|
+
|| Util::equalsLiteral("current", test)
|
|
261
|
+
|| Util::equalsLiteral("any", test)
|
|
262
|
+
|| Util::equalsLiteral("has", test)
|
|
263
|
+
|| Util::equalsLiteral("host", test)
|
|
264
|
+
|| Util::equalsLiteral("host-context", test);
|
|
265
|
+
}
|
|
266
|
+
// EO isSelectorPseudoClass
|
|
267
|
+
|
|
268
|
+
// ###########################################################################
|
|
269
|
+
// Pseudo-element selectors that take unadorned selectors as arguments.
|
|
270
|
+
// ###########################################################################
|
|
271
|
+
inline bool isSelectorPseudoElement(const sass::string& test)
|
|
272
|
+
{
|
|
273
|
+
return Util::equalsLiteral("slotted", test);
|
|
274
|
+
}
|
|
275
|
+
// EO isSelectorPseudoElement
|
|
276
|
+
|
|
277
|
+
// ###########################################################################
|
|
278
|
+
// Pseudo-element selectors that has binominals
|
|
279
|
+
// ###########################################################################
|
|
280
|
+
inline bool isSelectorPseudoBinominal(const sass::string& test)
|
|
281
|
+
{
|
|
282
|
+
return Util::equalsLiteral("nth-child", test)
|
|
283
|
+
|| Util::equalsLiteral("nth-last-child", test);
|
|
284
|
+
}
|
|
285
|
+
// isSelectorPseudoBinominal
|
|
286
|
+
|
|
287
|
+
// ###########################################################################
|
|
288
|
+
// ###########################################################################
|
|
289
|
+
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
#endif
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
// sass.hpp must go before all system headers to get the
|
|
2
|
+
// __EXTENSIONS__ fix on Solaris.
|
|
3
|
+
#include "sass.hpp"
|
|
4
|
+
|
|
5
|
+
#include "ast_selectors.hpp"
|
|
6
|
+
|
|
7
|
+
namespace Sass {
|
|
8
|
+
|
|
9
|
+
/*#########################################################################*/
|
|
10
|
+
// Compare against base class on right hand side
|
|
11
|
+
// try to find the most specialized implementation
|
|
12
|
+
/*#########################################################################*/
|
|
13
|
+
|
|
14
|
+
// Selector lists can be compared to comma lists
|
|
15
|
+
bool SelectorList::operator== (const Expression& rhs) const
|
|
16
|
+
{
|
|
17
|
+
if (auto l = Cast<List>(&rhs)) { return *this == *l; }
|
|
18
|
+
if (auto s = Cast<Selector>(&rhs)) { return *this == *s; }
|
|
19
|
+
if (Cast<String>(&rhs) || Cast<Null>(&rhs)) { return false; }
|
|
20
|
+
throw std::runtime_error("invalid selector base classes to compare");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Selector lists can be compared to comma lists
|
|
24
|
+
bool SelectorList::operator== (const Selector& rhs) const
|
|
25
|
+
{
|
|
26
|
+
if (auto sel = Cast<SelectorList>(&rhs)) { return *this == *sel; }
|
|
27
|
+
if (auto sel = Cast<ComplexSelector>(&rhs)) { return *this == *sel; }
|
|
28
|
+
if (auto sel = Cast<CompoundSelector>(&rhs)) { return *this == *sel; }
|
|
29
|
+
if (auto sel = Cast<SimpleSelector>(&rhs)) { return *this == *sel; }
|
|
30
|
+
if (auto list = Cast<List>(&rhs)) { return *this == *list; }
|
|
31
|
+
throw std::runtime_error("invalid selector base classes to compare");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
bool ComplexSelector::operator== (const Selector& rhs) const
|
|
35
|
+
{
|
|
36
|
+
if (auto sel = Cast<SelectorList>(&rhs)) { return *this == *sel; }
|
|
37
|
+
if (auto sel = Cast<ComplexSelector>(&rhs)) { return *sel == *this; }
|
|
38
|
+
if (auto sel = Cast<CompoundSelector>(&rhs)) { return *this == *sel; }
|
|
39
|
+
if (auto sel = Cast<SimpleSelector>(&rhs)) { return *this == *sel; }
|
|
40
|
+
throw std::runtime_error("invalid selector base classes to compare");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
bool SelectorCombinator::operator== (const Selector& rhs) const
|
|
44
|
+
{
|
|
45
|
+
if (auto cpx = Cast<SelectorCombinator>(&rhs)) { return *this == *cpx; }
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
bool CompoundSelector::operator== (const Selector& rhs) const
|
|
50
|
+
{
|
|
51
|
+
if (auto sel = Cast<SimpleSelector>(&rhs)) { return *this == *sel; }
|
|
52
|
+
if (auto sel = Cast<SelectorList>(&rhs)) { return *this == *sel; }
|
|
53
|
+
if (auto sel = Cast<ComplexSelector>(&rhs)) { return *this == *sel; }
|
|
54
|
+
if (auto sel = Cast<CompoundSelector>(&rhs)) { return *this == *sel; }
|
|
55
|
+
throw std::runtime_error("invalid selector base classes to compare");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
bool SimpleSelector::operator== (const Selector& rhs) const
|
|
59
|
+
{
|
|
60
|
+
if (auto sel = Cast<SelectorList>(&rhs)) { return *this == *sel; }
|
|
61
|
+
if (auto sel = Cast<ComplexSelector>(&rhs)) { return *this == *sel; }
|
|
62
|
+
if (auto sel = Cast<CompoundSelector>(&rhs)) { return *this == *sel; }
|
|
63
|
+
if (auto sel = Cast<SimpleSelector>(&rhs)) return *this == *sel;
|
|
64
|
+
throw std::runtime_error("invalid selector base classes to compare");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/*#########################################################################*/
|
|
68
|
+
/*#########################################################################*/
|
|
69
|
+
|
|
70
|
+
bool SelectorList::operator== (const SelectorList& rhs) const
|
|
71
|
+
{
|
|
72
|
+
if (&rhs == this) return true;
|
|
73
|
+
if (rhs.length() != length()) return false;
|
|
74
|
+
std::unordered_set<const ComplexSelector*, PtrObjHash, PtrObjEquality> lhs_set;
|
|
75
|
+
lhs_set.reserve(length());
|
|
76
|
+
for (const ComplexSelectorObj& element : elements()) {
|
|
77
|
+
lhs_set.insert(element.ptr());
|
|
78
|
+
}
|
|
79
|
+
for (const ComplexSelectorObj& element : rhs.elements()) {
|
|
80
|
+
if (lhs_set.find(element.ptr()) == lhs_set.end()) return false;
|
|
81
|
+
}
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
/*#########################################################################*/
|
|
88
|
+
// Compare SelectorList against all other selector types
|
|
89
|
+
/*#########################################################################*/
|
|
90
|
+
|
|
91
|
+
bool SelectorList::operator== (const ComplexSelector& rhs) const
|
|
92
|
+
{
|
|
93
|
+
// If both are empty they are equal
|
|
94
|
+
if (empty() && rhs.empty()) return true;
|
|
95
|
+
// Must have exactly one item
|
|
96
|
+
if (length() != 1) return false;
|
|
97
|
+
// Compare simple selectors
|
|
98
|
+
return *get(0) == rhs;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
bool SelectorList::operator== (const CompoundSelector& rhs) const
|
|
102
|
+
{
|
|
103
|
+
// If both are empty they are equal
|
|
104
|
+
if (empty() && rhs.empty()) return true;
|
|
105
|
+
// Must have exactly one item
|
|
106
|
+
if (length() != 1) return false;
|
|
107
|
+
// Compare simple selectors
|
|
108
|
+
return *get(0) == rhs;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
bool SelectorList::operator== (const SimpleSelector& rhs) const
|
|
112
|
+
{
|
|
113
|
+
// If both are empty they are equal
|
|
114
|
+
if (empty() && rhs.empty()) return true;
|
|
115
|
+
// Must have exactly one item
|
|
116
|
+
if (length() != 1) return false;
|
|
117
|
+
// Compare simple selectors
|
|
118
|
+
return *get(0) == rhs;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/*#########################################################################*/
|
|
122
|
+
// Compare ComplexSelector against itself
|
|
123
|
+
/*#########################################################################*/
|
|
124
|
+
|
|
125
|
+
bool ComplexSelector::operator== (const ComplexSelector& rhs) const
|
|
126
|
+
{
|
|
127
|
+
size_t len = length();
|
|
128
|
+
size_t rlen = rhs.length();
|
|
129
|
+
if (len != rlen) return false;
|
|
130
|
+
for (size_t i = 0; i < len; i += 1) {
|
|
131
|
+
if (*get(i) != *rhs.get(i)) return false;
|
|
132
|
+
}
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/*#########################################################################*/
|
|
137
|
+
// Compare ComplexSelector against all other selector types
|
|
138
|
+
/*#########################################################################*/
|
|
139
|
+
|
|
140
|
+
bool ComplexSelector::operator== (const SelectorList& rhs) const
|
|
141
|
+
{
|
|
142
|
+
// If both are empty they are equal
|
|
143
|
+
if (empty() && rhs.empty()) return true;
|
|
144
|
+
// Must have exactly one item
|
|
145
|
+
if (rhs.length() != 1) return false;
|
|
146
|
+
// Compare complex selector
|
|
147
|
+
return *this == *rhs.get(0);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
bool ComplexSelector::operator== (const CompoundSelector& rhs) const
|
|
151
|
+
{
|
|
152
|
+
// If both are empty they are equal
|
|
153
|
+
if (empty() && rhs.empty()) return true;
|
|
154
|
+
// Must have exactly one item
|
|
155
|
+
if (length() != 1) return false;
|
|
156
|
+
// Compare compound selector
|
|
157
|
+
return *get(0) == rhs;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
bool ComplexSelector::operator== (const SimpleSelector& rhs) const
|
|
161
|
+
{
|
|
162
|
+
// If both are empty they are equal
|
|
163
|
+
if (empty() && rhs.empty()) return true;
|
|
164
|
+
// Must have exactly one item
|
|
165
|
+
if (length() != 1) return false;
|
|
166
|
+
// Compare simple selectors
|
|
167
|
+
return *get(0) == rhs;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/*#########################################################################*/
|
|
171
|
+
// Compare SelectorCombinator against itself
|
|
172
|
+
/*#########################################################################*/
|
|
173
|
+
|
|
174
|
+
bool SelectorCombinator::operator==(const SelectorCombinator& rhs) const
|
|
175
|
+
{
|
|
176
|
+
return combinator() == rhs.combinator();
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/*#########################################################################*/
|
|
180
|
+
// Compare SelectorCombinator against SelectorComponent
|
|
181
|
+
/*#########################################################################*/
|
|
182
|
+
|
|
183
|
+
bool SelectorCombinator::operator==(const SelectorComponent& rhs) const
|
|
184
|
+
{
|
|
185
|
+
if (const SelectorCombinator * sel = rhs.getCombinator()) {
|
|
186
|
+
return *this == *sel;
|
|
187
|
+
}
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
bool CompoundSelector::operator==(const SelectorComponent& rhs) const
|
|
192
|
+
{
|
|
193
|
+
if (const CompoundSelector * sel = rhs.getCompound()) {
|
|
194
|
+
return *this == *sel;
|
|
195
|
+
}
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/*#########################################################################*/
|
|
200
|
+
// Compare CompoundSelector against itself
|
|
201
|
+
/*#########################################################################*/
|
|
202
|
+
// ToDo: Verifiy implementation
|
|
203
|
+
/*#########################################################################*/
|
|
204
|
+
|
|
205
|
+
bool CompoundSelector::operator== (const CompoundSelector& rhs) const
|
|
206
|
+
{
|
|
207
|
+
// std::cerr << "comp vs comp\n";
|
|
208
|
+
if (&rhs == this) return true;
|
|
209
|
+
if (rhs.length() != length()) return false;
|
|
210
|
+
std::unordered_set<const SimpleSelector*, PtrObjHash, PtrObjEquality> lhs_set;
|
|
211
|
+
lhs_set.reserve(length());
|
|
212
|
+
for (const SimpleSelectorObj& element : elements()) {
|
|
213
|
+
lhs_set.insert(element.ptr());
|
|
214
|
+
}
|
|
215
|
+
// there is no break?!
|
|
216
|
+
for (const SimpleSelectorObj& element : rhs.elements()) {
|
|
217
|
+
if (lhs_set.find(element.ptr()) == lhs_set.end()) return false;
|
|
218
|
+
}
|
|
219
|
+
return true;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
/*#########################################################################*/
|
|
224
|
+
// Compare CompoundSelector against all other selector types
|
|
225
|
+
/*#########################################################################*/
|
|
226
|
+
|
|
227
|
+
bool CompoundSelector::operator== (const SelectorList& rhs) const
|
|
228
|
+
{
|
|
229
|
+
// If both are empty they are equal
|
|
230
|
+
if (empty() && rhs.empty()) return true;
|
|
231
|
+
// Must have exactly one item
|
|
232
|
+
if (rhs.length() != 1) return false;
|
|
233
|
+
// Compare complex selector
|
|
234
|
+
return *this == *rhs.get(0);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
bool CompoundSelector::operator== (const ComplexSelector& rhs) const
|
|
238
|
+
{
|
|
239
|
+
// If both are empty they are equal
|
|
240
|
+
if (empty() && rhs.empty()) return true;
|
|
241
|
+
// Must have exactly one item
|
|
242
|
+
if (rhs.length() != 1) return false;
|
|
243
|
+
// Compare compound selector
|
|
244
|
+
return *this == *rhs.get(0);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
bool CompoundSelector::operator== (const SimpleSelector& rhs) const
|
|
248
|
+
{
|
|
249
|
+
// If both are empty they are equal
|
|
250
|
+
if (empty() && rhs.empty()) return false;
|
|
251
|
+
// Must have exactly one item
|
|
252
|
+
size_t rlen = length();
|
|
253
|
+
if (rlen > 1) return false;
|
|
254
|
+
if (rlen == 0) return true;
|
|
255
|
+
// Compare simple selectors
|
|
256
|
+
return *get(0) < rhs;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/*#########################################################################*/
|
|
260
|
+
// Compare SimpleSelector against itself (upcast from abstract base)
|
|
261
|
+
/*#########################################################################*/
|
|
262
|
+
|
|
263
|
+
// DOES NOT EXIST FOR ABSTRACT BASE CLASS
|
|
264
|
+
|
|
265
|
+
/*#########################################################################*/
|
|
266
|
+
// Compare SimpleSelector against all other selector types
|
|
267
|
+
/*#########################################################################*/
|
|
268
|
+
|
|
269
|
+
bool SimpleSelector::operator== (const SelectorList& rhs) const
|
|
270
|
+
{
|
|
271
|
+
// If both are empty they are equal
|
|
272
|
+
if (empty() && rhs.empty()) return true;
|
|
273
|
+
// Must have exactly one item
|
|
274
|
+
if (rhs.length() != 1) return false;
|
|
275
|
+
// Compare complex selector
|
|
276
|
+
return *this == *rhs.get(0);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
bool SimpleSelector::operator== (const ComplexSelector& rhs) const
|
|
280
|
+
{
|
|
281
|
+
// If both are empty they are equal
|
|
282
|
+
if (empty() && rhs.empty()) return true;
|
|
283
|
+
// Must have exactly one item
|
|
284
|
+
if (rhs.length() != 1) return false;
|
|
285
|
+
// Compare compound selector
|
|
286
|
+
return *this == *rhs.get(0);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
bool SimpleSelector::operator== (const CompoundSelector& rhs) const
|
|
290
|
+
{
|
|
291
|
+
// If both are empty they are equal
|
|
292
|
+
if (empty() && rhs.empty()) return false;
|
|
293
|
+
// Must have exactly one item
|
|
294
|
+
if (rhs.length() != 1) return false;
|
|
295
|
+
// Compare simple selector
|
|
296
|
+
return *this == *rhs.get(0);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/*#########################################################################*/
|
|
300
|
+
/*#########################################################################*/
|
|
301
|
+
|
|
302
|
+
bool IDSelector::operator== (const SimpleSelector& rhs) const
|
|
303
|
+
{
|
|
304
|
+
auto sel = Cast<IDSelector>(&rhs);
|
|
305
|
+
return sel ? *this == *sel : false;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
bool TypeSelector::operator== (const SimpleSelector& rhs) const
|
|
309
|
+
{
|
|
310
|
+
auto sel = Cast<TypeSelector>(&rhs);
|
|
311
|
+
return sel ? *this == *sel : false;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
bool ClassSelector::operator== (const SimpleSelector& rhs) const
|
|
315
|
+
{
|
|
316
|
+
auto sel = Cast<ClassSelector>(&rhs);
|
|
317
|
+
return sel ? *this == *sel : false;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
bool PseudoSelector::operator== (const SimpleSelector& rhs) const
|
|
321
|
+
{
|
|
322
|
+
auto sel = Cast<PseudoSelector>(&rhs);
|
|
323
|
+
return sel ? *this == *sel : false;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
bool AttributeSelector::operator== (const SimpleSelector& rhs) const
|
|
327
|
+
{
|
|
328
|
+
auto sel = Cast<AttributeSelector>(&rhs);
|
|
329
|
+
return sel ? *this == *sel : false;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
bool PlaceholderSelector::operator== (const SimpleSelector& rhs) const
|
|
333
|
+
{
|
|
334
|
+
auto sel = Cast<PlaceholderSelector>(&rhs);
|
|
335
|
+
return sel ? *this == *sel : false;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/*#########################################################################*/
|
|
339
|
+
/*#########################################################################*/
|
|
340
|
+
|
|
341
|
+
bool IDSelector::operator== (const IDSelector& rhs) const
|
|
342
|
+
{
|
|
343
|
+
// ID has no namespacing
|
|
344
|
+
return name() == rhs.name();
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
bool TypeSelector::operator== (const TypeSelector& rhs) const
|
|
348
|
+
{
|
|
349
|
+
return is_ns_eq(rhs) && name() == rhs.name();
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
bool ClassSelector::operator== (const ClassSelector& rhs) const
|
|
353
|
+
{
|
|
354
|
+
// Class has no namespacing
|
|
355
|
+
return name() == rhs.name();
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
bool PlaceholderSelector::operator== (const PlaceholderSelector& rhs) const
|
|
359
|
+
{
|
|
360
|
+
// Placeholder has no namespacing
|
|
361
|
+
return name() == rhs.name();
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
bool AttributeSelector::operator== (const AttributeSelector& rhs) const
|
|
365
|
+
{
|
|
366
|
+
// smaller return, equal go on, bigger abort
|
|
367
|
+
if (is_ns_eq(rhs)) {
|
|
368
|
+
if (name() != rhs.name()) return false;
|
|
369
|
+
if (matcher() != rhs.matcher()) return false;
|
|
370
|
+
if (modifier() != rhs.modifier()) return false;
|
|
371
|
+
const String* lhs_val = value();
|
|
372
|
+
const String* rhs_val = rhs.value();
|
|
373
|
+
return PtrObjEquality()(lhs_val, rhs_val);
|
|
374
|
+
}
|
|
375
|
+
else { return false; }
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
bool PseudoSelector::operator== (const PseudoSelector& rhs) const
|
|
379
|
+
{
|
|
380
|
+
if (is_ns_eq(rhs)) {
|
|
381
|
+
if (name() != rhs.name()) return false;
|
|
382
|
+
if (isElement() != rhs.isElement()) return false;
|
|
383
|
+
const String* lhs_arg = argument();
|
|
384
|
+
const String* rhs_arg = rhs.argument();
|
|
385
|
+
if (!PtrObjEquality()(lhs_arg, rhs_arg)) return false;
|
|
386
|
+
const SelectorList* lhs_sel = selector();
|
|
387
|
+
const SelectorList* rhs_sel = rhs.selector();
|
|
388
|
+
return PtrObjEquality()(lhs_sel, rhs_sel);
|
|
389
|
+
}
|
|
390
|
+
else { return false; }
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/*#########################################################################*/
|
|
394
|
+
/*#########################################################################*/
|
|
395
|
+
|
|
396
|
+
}
|