sassc4 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/.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 +316 -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 +1070 -0
- data/ext/libsass/src/ast_selectors.hpp +523 -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/color_spaces.cpp +241 -0
- data/ext/libsass/src/color_spaces.hpp +227 -0
- data/ext/libsass/src/constants.cpp +199 -0
- data/ext/libsass/src/constants.hpp +200 -0
- data/ext/libsass/src/context.cpp +870 -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 +964 -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 +239 -0
- data/ext/libsass/src/error_handling.hpp +248 -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 +1226 -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 +836 -0
- data/ext/libsass/src/fn_colors.hpp +99 -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 +248 -0
- data/ext/libsass/src/fn_miscs.hpp +40 -0
- data/ext/libsass/src/fn_numbers.cpp +246 -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 +159 -0
- data/ext/libsass/src/fn_utils.hpp +62 -0
- data/ext/libsass/src/inspect.cpp +1126 -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 +3059 -0
- data/ext/libsass/src/parser.hpp +395 -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 +163 -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 +742 -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 +64 -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/css_color_level4_test.rb +168 -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 +396 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
#include <numeric>
|
|
2
|
+
|
|
3
|
+
#include "parser.hpp"
|
|
4
|
+
#include "extender.hpp"
|
|
5
|
+
#include "listize.hpp"
|
|
6
|
+
#include "fn_utils.hpp"
|
|
7
|
+
#include "fn_selectors.hpp"
|
|
8
|
+
|
|
9
|
+
namespace Sass {
|
|
10
|
+
|
|
11
|
+
namespace Functions {
|
|
12
|
+
|
|
13
|
+
Signature selector_nest_sig = "selector-nest($selectors...)";
|
|
14
|
+
BUILT_IN(selector_nest)
|
|
15
|
+
{
|
|
16
|
+
List* arglist = ARG("$selectors", List);
|
|
17
|
+
|
|
18
|
+
// Not enough parameters
|
|
19
|
+
if (arglist->length() == 0) {
|
|
20
|
+
error(
|
|
21
|
+
"$selectors: At least one selector must be passed for `selector-nest'",
|
|
22
|
+
pstate, traces);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Parse args into vector of selectors
|
|
26
|
+
SelectorStack parsedSelectors;
|
|
27
|
+
for (size_t i = 0, L = arglist->length(); i < L; ++i) {
|
|
28
|
+
ExpressionObj exp = Cast<Expression>(arglist->value_at_index(i));
|
|
29
|
+
if (exp->concrete_type() == Expression::NULL_VAL) {
|
|
30
|
+
error(
|
|
31
|
+
"$selectors: null is not a valid selector: it must be a string,\n"
|
|
32
|
+
"a list of strings, or a list of lists of strings for 'selector-nest'",
|
|
33
|
+
pstate, traces);
|
|
34
|
+
}
|
|
35
|
+
if (String_Constant_Obj str = Cast<String_Constant>(exp)) {
|
|
36
|
+
str->quote_mark(0);
|
|
37
|
+
}
|
|
38
|
+
sass::string exp_src = exp->to_string(ctx.c_options);
|
|
39
|
+
ItplFile* source = SASS_MEMORY_NEW(ItplFile, exp_src.c_str(), exp->pstate());
|
|
40
|
+
SelectorListObj sel = Parser::parse_selector(source, ctx, traces);
|
|
41
|
+
parsedSelectors.push_back(sel);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Nothing to do
|
|
45
|
+
if( parsedSelectors.empty() ) {
|
|
46
|
+
return SASS_MEMORY_NEW(Null, pstate);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Set the first element as the `result`, keep
|
|
50
|
+
// appending to as we go down the parsedSelector vector.
|
|
51
|
+
SelectorStack::iterator itr = parsedSelectors.begin();
|
|
52
|
+
SelectorListObj& result = *itr;
|
|
53
|
+
++itr;
|
|
54
|
+
|
|
55
|
+
for(;itr != parsedSelectors.end(); ++itr) {
|
|
56
|
+
SelectorListObj& child = *itr;
|
|
57
|
+
original_stack.push_back(result);
|
|
58
|
+
SelectorListObj rv = child->resolve_parent_refs(original_stack, traces);
|
|
59
|
+
result->elements(rv->elements());
|
|
60
|
+
original_stack.pop_back();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return Cast<Value>(Listize::perform(result));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
Signature selector_append_sig = "selector-append($selectors...)";
|
|
67
|
+
BUILT_IN(selector_append)
|
|
68
|
+
{
|
|
69
|
+
List* arglist = ARG("$selectors", List);
|
|
70
|
+
|
|
71
|
+
// Not enough parameters
|
|
72
|
+
if (arglist->empty()) {
|
|
73
|
+
error(
|
|
74
|
+
"$selectors: At least one selector must be "
|
|
75
|
+
"passed for `selector-append'",
|
|
76
|
+
pstate, traces);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Parse args into vector of selectors
|
|
80
|
+
SelectorStack parsedSelectors;
|
|
81
|
+
parsedSelectors.push_back({});
|
|
82
|
+
for (size_t i = 0, L = arglist->length(); i < L; ++i) {
|
|
83
|
+
Expression* exp = Cast<Expression>(arglist->value_at_index(i));
|
|
84
|
+
if (exp->concrete_type() == Expression::NULL_VAL) {
|
|
85
|
+
error(
|
|
86
|
+
"$selectors: null is not a valid selector: it must be a string,\n"
|
|
87
|
+
"a list of strings, or a list of lists of strings for 'selector-append'",
|
|
88
|
+
pstate, traces);
|
|
89
|
+
}
|
|
90
|
+
if (String_Constant* str = Cast<String_Constant>(exp)) {
|
|
91
|
+
str->quote_mark(0);
|
|
92
|
+
}
|
|
93
|
+
sass::string exp_src = exp->to_string();
|
|
94
|
+
ItplFile* source = SASS_MEMORY_NEW(ItplFile, exp_src.c_str(), exp->pstate());
|
|
95
|
+
SelectorListObj sel = Parser::parse_selector(source, ctx, traces, true);
|
|
96
|
+
|
|
97
|
+
for (auto& complex : sel->elements()) {
|
|
98
|
+
if (complex->empty()) {
|
|
99
|
+
complex->append(SASS_MEMORY_NEW(CompoundSelector, "[append]"));
|
|
100
|
+
}
|
|
101
|
+
if (CompoundSelector* comp = Cast<CompoundSelector>(complex->first())) {
|
|
102
|
+
comp->hasRealParent(true);
|
|
103
|
+
complex->chroots(true);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (parsedSelectors.size() > 1) {
|
|
108
|
+
|
|
109
|
+
if (!sel->has_real_parent_ref()) {
|
|
110
|
+
auto parent = parsedSelectors.back();
|
|
111
|
+
for (auto& complex : parent->elements()) {
|
|
112
|
+
if (CompoundSelector* comp = Cast<CompoundSelector>(complex->first())) {
|
|
113
|
+
comp->hasRealParent(false);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
error("Can't append \"" + sel->to_string() + "\" to \"" +
|
|
117
|
+
parent->to_string() + "\" for `selector-append'",
|
|
118
|
+
pstate, traces);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Build the resolved stack from the left. It's cheaper to directly
|
|
122
|
+
// calculate and update each resolved selcted from the left, than to
|
|
123
|
+
// recursively calculate them from the right side, as we would need
|
|
124
|
+
// to go through the whole stack depth to build the final results.
|
|
125
|
+
// E.g. 'a', 'b', 'x, y' => 'a' => 'a b' => 'a b x, a b y'
|
|
126
|
+
// vs 'a', 'b', 'x, y' => 'x' => 'b x' => 'a b x', 'y' ...
|
|
127
|
+
parsedSelectors.push_back(sel->resolve_parent_refs(parsedSelectors, traces, true));
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
parsedSelectors.push_back(sel);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Nothing to do
|
|
135
|
+
if( parsedSelectors.empty() ) {
|
|
136
|
+
return SASS_MEMORY_NEW(Null, pstate);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return Cast<Value>(Listize::perform(parsedSelectors.back()));
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
Signature selector_unify_sig = "selector-unify($selector1, $selector2)";
|
|
143
|
+
BUILT_IN(selector_unify)
|
|
144
|
+
{
|
|
145
|
+
SelectorListObj selector1 = ARGSELS("$selector1");
|
|
146
|
+
SelectorListObj selector2 = ARGSELS("$selector2");
|
|
147
|
+
SelectorListObj result = selector1->unifyWith(selector2);
|
|
148
|
+
return Cast<Value>(Listize::perform(result));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
Signature simple_selectors_sig = "simple-selectors($selector)";
|
|
152
|
+
BUILT_IN(simple_selectors)
|
|
153
|
+
{
|
|
154
|
+
CompoundSelectorObj sel = ARGSEL("$selector");
|
|
155
|
+
|
|
156
|
+
List* l = SASS_MEMORY_NEW(List, sel->pstate(), sel->length(), SASS_COMMA);
|
|
157
|
+
|
|
158
|
+
for (size_t i = 0, L = sel->length(); i < L; ++i) {
|
|
159
|
+
const SimpleSelectorObj& ss = sel->get(i);
|
|
160
|
+
sass::string ss_string = ss->to_string() ;
|
|
161
|
+
l->append(SASS_MEMORY_NEW(String_Quoted, ss->pstate(), ss_string));
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return l;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
Signature selector_extend_sig = "selector-extend($selector, $extendee, $extender)";
|
|
168
|
+
BUILT_IN(selector_extend)
|
|
169
|
+
{
|
|
170
|
+
SelectorListObj selector = ARGSELS("$selector");
|
|
171
|
+
SelectorListObj target = ARGSELS("$extendee");
|
|
172
|
+
SelectorListObj source = ARGSELS("$extender");
|
|
173
|
+
SelectorListObj result = Extender::extend(selector, source, target, traces);
|
|
174
|
+
return Cast<Value>(Listize::perform(result));
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
Signature selector_replace_sig = "selector-replace($selector, $original, $replacement)";
|
|
178
|
+
BUILT_IN(selector_replace)
|
|
179
|
+
{
|
|
180
|
+
SelectorListObj selector = ARGSELS("$selector");
|
|
181
|
+
SelectorListObj target = ARGSELS("$original");
|
|
182
|
+
SelectorListObj source = ARGSELS("$replacement");
|
|
183
|
+
SelectorListObj result = Extender::replace(selector, source, target, traces);
|
|
184
|
+
return Cast<Value>(Listize::perform(result));
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
Signature selector_parse_sig = "selector-parse($selector)";
|
|
188
|
+
BUILT_IN(selector_parse)
|
|
189
|
+
{
|
|
190
|
+
SelectorListObj selector = ARGSELS("$selector");
|
|
191
|
+
return Cast<Value>(Listize::perform(selector));
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
Signature is_superselector_sig = "is-superselector($super, $sub)";
|
|
195
|
+
BUILT_IN(is_superselector)
|
|
196
|
+
{
|
|
197
|
+
SelectorListObj sel_sup = ARGSELS("$super");
|
|
198
|
+
SelectorListObj sel_sub = ARGSELS("$sub");
|
|
199
|
+
bool result = sel_sup->isSuperselectorOf(sel_sub);
|
|
200
|
+
return SASS_MEMORY_NEW(Boolean, pstate, result);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#ifndef SASS_FN_SELECTORS_H
|
|
2
|
+
#define SASS_FN_SELECTORS_H
|
|
3
|
+
|
|
4
|
+
#include "fn_utils.hpp"
|
|
5
|
+
|
|
6
|
+
namespace Sass {
|
|
7
|
+
|
|
8
|
+
namespace Functions {
|
|
9
|
+
|
|
10
|
+
#define ARGSEL(argname) get_arg_sel(argname, env, sig, pstate, traces, ctx)
|
|
11
|
+
#define ARGSELS(argname) get_arg_sels(argname, env, sig, pstate, traces, ctx)
|
|
12
|
+
|
|
13
|
+
BUILT_IN(selector_nest);
|
|
14
|
+
BUILT_IN(selector_append);
|
|
15
|
+
BUILT_IN(selector_extend);
|
|
16
|
+
BUILT_IN(selector_replace);
|
|
17
|
+
BUILT_IN(selector_unify);
|
|
18
|
+
BUILT_IN(is_superselector);
|
|
19
|
+
BUILT_IN(simple_selectors);
|
|
20
|
+
BUILT_IN(selector_parse);
|
|
21
|
+
|
|
22
|
+
extern Signature selector_nest_sig;
|
|
23
|
+
extern Signature selector_append_sig;
|
|
24
|
+
extern Signature selector_extend_sig;
|
|
25
|
+
extern Signature selector_replace_sig;
|
|
26
|
+
extern Signature selector_unify_sig;
|
|
27
|
+
extern Signature is_superselector_sig;
|
|
28
|
+
extern Signature simple_selectors_sig;
|
|
29
|
+
extern Signature selector_parse_sig;
|
|
30
|
+
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
#endif
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
// sass.hpp must go before all system headers to get the
|
|
2
|
+
// __EXTENSIONS__ fix on Solaris.
|
|
3
|
+
#include "sass.hpp"
|
|
4
|
+
|
|
5
|
+
#include "utf8.h"
|
|
6
|
+
#include "ast.hpp"
|
|
7
|
+
#include "fn_utils.hpp"
|
|
8
|
+
#include "fn_strings.hpp"
|
|
9
|
+
#include "util_string.hpp"
|
|
10
|
+
|
|
11
|
+
namespace Sass {
|
|
12
|
+
|
|
13
|
+
namespace Functions {
|
|
14
|
+
|
|
15
|
+
void handle_utf8_error (const SourceSpan& pstate, Backtraces traces)
|
|
16
|
+
{
|
|
17
|
+
try {
|
|
18
|
+
throw;
|
|
19
|
+
}
|
|
20
|
+
catch (utf8::invalid_code_point&) {
|
|
21
|
+
sass::string msg("utf8::invalid_code_point");
|
|
22
|
+
error(msg, pstate, traces);
|
|
23
|
+
}
|
|
24
|
+
catch (utf8::not_enough_room&) {
|
|
25
|
+
sass::string msg("utf8::not_enough_room");
|
|
26
|
+
error(msg, pstate, traces);
|
|
27
|
+
}
|
|
28
|
+
catch (utf8::invalid_utf8&) {
|
|
29
|
+
sass::string msg("utf8::invalid_utf8");
|
|
30
|
+
error(msg, pstate, traces);
|
|
31
|
+
}
|
|
32
|
+
catch (...) { throw; }
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
///////////////////
|
|
36
|
+
// STRING FUNCTIONS
|
|
37
|
+
///////////////////
|
|
38
|
+
|
|
39
|
+
Signature unquote_sig = "unquote($string)";
|
|
40
|
+
BUILT_IN(sass_unquote)
|
|
41
|
+
{
|
|
42
|
+
AST_Node_Obj arg = env["$string"];
|
|
43
|
+
if (String_Quoted* string_quoted = Cast<String_Quoted>(arg)) {
|
|
44
|
+
String_Constant* result = SASS_MEMORY_NEW(String_Constant, pstate, string_quoted->value());
|
|
45
|
+
// remember if the string was quoted (color tokens)
|
|
46
|
+
result->is_delayed(true); // delay colors
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
else if (String_Constant* str = Cast<String_Constant>(arg)) {
|
|
50
|
+
return str;
|
|
51
|
+
}
|
|
52
|
+
else if (Value* ex = Cast<Value>(arg)) {
|
|
53
|
+
Sass_Output_Style oldstyle = ctx.c_options.output_style;
|
|
54
|
+
ctx.c_options.output_style = SASS_STYLE_NESTED;
|
|
55
|
+
sass::string val(arg->to_string(ctx.c_options));
|
|
56
|
+
val = Cast<Null>(arg) ? "null" : val;
|
|
57
|
+
ctx.c_options.output_style = oldstyle;
|
|
58
|
+
|
|
59
|
+
deprecated_function("Passing " + val + ", a non-string value, to unquote()", pstate);
|
|
60
|
+
return ex;
|
|
61
|
+
}
|
|
62
|
+
throw std::runtime_error("Invalid Data Type for unquote");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
Signature quote_sig = "quote($string)";
|
|
66
|
+
BUILT_IN(sass_quote)
|
|
67
|
+
{
|
|
68
|
+
const String_Constant* s = ARG("$string", String_Constant);
|
|
69
|
+
String_Quoted *result = SASS_MEMORY_NEW(
|
|
70
|
+
String_Quoted, pstate, s->value(),
|
|
71
|
+
/*q=*/'\0', /*keep_utf8_escapes=*/false, /*skip_unquoting=*/true);
|
|
72
|
+
result->quote_mark('*');
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
Signature str_length_sig = "str-length($string)";
|
|
77
|
+
BUILT_IN(str_length)
|
|
78
|
+
{
|
|
79
|
+
size_t len = sass::string::npos;
|
|
80
|
+
try {
|
|
81
|
+
String_Constant* s = ARG("$string", String_Constant);
|
|
82
|
+
len = UTF_8::code_point_count(s->value(), 0, s->value().size());
|
|
83
|
+
|
|
84
|
+
}
|
|
85
|
+
// handle any invalid utf8 errors
|
|
86
|
+
// other errors will be re-thrown
|
|
87
|
+
catch (...) { handle_utf8_error(pstate, traces); }
|
|
88
|
+
// return something even if we had an error (-1)
|
|
89
|
+
return SASS_MEMORY_NEW(Number, pstate, (double)len);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
Signature str_insert_sig = "str-insert($string, $insert, $index)";
|
|
93
|
+
BUILT_IN(str_insert)
|
|
94
|
+
{
|
|
95
|
+
sass::string str;
|
|
96
|
+
try {
|
|
97
|
+
String_Constant* s = ARG("$string", String_Constant);
|
|
98
|
+
str = s->value();
|
|
99
|
+
String_Constant* i = ARG("$insert", String_Constant);
|
|
100
|
+
sass::string ins = i->value();
|
|
101
|
+
double index = ARGVAL("$index");
|
|
102
|
+
if (index != (int)index) {
|
|
103
|
+
sass::ostream strm;
|
|
104
|
+
strm << "$index: ";
|
|
105
|
+
strm << std::to_string(index);
|
|
106
|
+
strm << " is not an int";
|
|
107
|
+
error(strm.str(), pstate, traces);
|
|
108
|
+
}
|
|
109
|
+
size_t len = UTF_8::code_point_count(str, 0, str.size());
|
|
110
|
+
|
|
111
|
+
if (index > 0 && index <= len) {
|
|
112
|
+
// positive and within string length
|
|
113
|
+
str.insert(UTF_8::offset_at_position(str, static_cast<size_t>(index) - 1), ins);
|
|
114
|
+
}
|
|
115
|
+
else if (index > len) {
|
|
116
|
+
// positive and past string length
|
|
117
|
+
str += ins;
|
|
118
|
+
}
|
|
119
|
+
else if (index == 0) {
|
|
120
|
+
str = ins + str;
|
|
121
|
+
}
|
|
122
|
+
else if (std::abs(index) <= len) {
|
|
123
|
+
// negative and within string length
|
|
124
|
+
index += len + 1;
|
|
125
|
+
str.insert(UTF_8::offset_at_position(str, static_cast<size_t>(index)), ins);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
// negative and past string length
|
|
129
|
+
str = ins + str;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (String_Quoted* ss = Cast<String_Quoted>(s)) {
|
|
133
|
+
if (ss->quote_mark()) str = quote(str);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// handle any invalid utf8 errors
|
|
137
|
+
// other errors will be re-thrown
|
|
138
|
+
catch (...) { handle_utf8_error(pstate, traces); }
|
|
139
|
+
return SASS_MEMORY_NEW(String_Quoted, pstate, str);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
Signature str_index_sig = "str-index($string, $substring)";
|
|
143
|
+
BUILT_IN(str_index)
|
|
144
|
+
{
|
|
145
|
+
size_t index = sass::string::npos;
|
|
146
|
+
try {
|
|
147
|
+
String_Constant* s = ARG("$string", String_Constant);
|
|
148
|
+
String_Constant* t = ARG("$substring", String_Constant);
|
|
149
|
+
sass::string str = s->value();
|
|
150
|
+
sass::string substr = t->value();
|
|
151
|
+
|
|
152
|
+
size_t c_index = str.find(substr);
|
|
153
|
+
if(c_index == sass::string::npos) {
|
|
154
|
+
return SASS_MEMORY_NEW(Null, pstate);
|
|
155
|
+
}
|
|
156
|
+
index = UTF_8::code_point_count(str, 0, c_index) + 1;
|
|
157
|
+
}
|
|
158
|
+
// handle any invalid utf8 errors
|
|
159
|
+
// other errors will be re-thrown
|
|
160
|
+
catch (...) { handle_utf8_error(pstate, traces); }
|
|
161
|
+
// return something even if we had an error (-1)
|
|
162
|
+
return SASS_MEMORY_NEW(Number, pstate, (double)index);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
Signature str_slice_sig = "str-slice($string, $start-at, $end-at:-1)";
|
|
166
|
+
BUILT_IN(str_slice)
|
|
167
|
+
{
|
|
168
|
+
sass::string newstr;
|
|
169
|
+
try {
|
|
170
|
+
String_Constant* s = ARG("$string", String_Constant);
|
|
171
|
+
double start_at = ARGVAL("$start-at");
|
|
172
|
+
double end_at = ARGVAL("$end-at");
|
|
173
|
+
|
|
174
|
+
if (start_at != (int)start_at) {
|
|
175
|
+
sass::ostream strm;
|
|
176
|
+
strm << "$start-at: ";
|
|
177
|
+
strm << std::to_string(start_at);
|
|
178
|
+
strm << " is not an int";
|
|
179
|
+
error(strm.str(), pstate, traces);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
String_Quoted* ss = Cast<String_Quoted>(s);
|
|
183
|
+
|
|
184
|
+
sass::string str(s->value());
|
|
185
|
+
|
|
186
|
+
size_t size = utf8::distance(str.begin(), str.end());
|
|
187
|
+
|
|
188
|
+
if (!Cast<Number>(env["$end-at"])) {
|
|
189
|
+
end_at = -1;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (end_at != (int)end_at) {
|
|
193
|
+
sass::ostream strm;
|
|
194
|
+
strm << "$end-at: ";
|
|
195
|
+
strm << std::to_string(end_at);
|
|
196
|
+
strm << " is not an int";
|
|
197
|
+
error(strm.str(), pstate, traces);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (end_at == 0 || (end_at + size) < 0) {
|
|
201
|
+
if (ss && ss->quote_mark()) newstr = quote("");
|
|
202
|
+
return SASS_MEMORY_NEW(String_Quoted, pstate, newstr);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (end_at < 0) {
|
|
206
|
+
end_at += size + 1;
|
|
207
|
+
if (end_at == 0) end_at = 1;
|
|
208
|
+
}
|
|
209
|
+
if (end_at > size) { end_at = (double)size; }
|
|
210
|
+
if (start_at < 0) {
|
|
211
|
+
start_at += size + 1;
|
|
212
|
+
if (start_at <= 0) start_at = 1;
|
|
213
|
+
}
|
|
214
|
+
else if (start_at == 0) { ++ start_at; }
|
|
215
|
+
|
|
216
|
+
if (start_at <= end_at)
|
|
217
|
+
{
|
|
218
|
+
sass::string::iterator start = str.begin();
|
|
219
|
+
utf8::advance(start, start_at - 1, str.end());
|
|
220
|
+
sass::string::iterator end = start;
|
|
221
|
+
utf8::advance(end, end_at - start_at + 1, str.end());
|
|
222
|
+
newstr = sass::string(start, end);
|
|
223
|
+
}
|
|
224
|
+
if (ss) {
|
|
225
|
+
if(ss->quote_mark()) newstr = quote(newstr);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
// handle any invalid utf8 errors
|
|
229
|
+
// other errors will be re-thrown
|
|
230
|
+
catch (...) { handle_utf8_error(pstate, traces); }
|
|
231
|
+
return SASS_MEMORY_NEW(String_Quoted, pstate, newstr);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
Signature to_upper_case_sig = "to-upper-case($string)";
|
|
235
|
+
BUILT_IN(to_upper_case)
|
|
236
|
+
{
|
|
237
|
+
String_Constant* s = ARG("$string", String_Constant);
|
|
238
|
+
sass::string str = s->value();
|
|
239
|
+
Util::ascii_str_toupper(&str);
|
|
240
|
+
|
|
241
|
+
if (String_Quoted* ss = Cast<String_Quoted>(s)) {
|
|
242
|
+
String_Quoted* cpy = SASS_MEMORY_COPY(ss);
|
|
243
|
+
cpy->value(str);
|
|
244
|
+
return cpy;
|
|
245
|
+
} else {
|
|
246
|
+
return SASS_MEMORY_NEW(String_Quoted, pstate, str);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
Signature to_lower_case_sig = "to-lower-case($string)";
|
|
251
|
+
BUILT_IN(to_lower_case)
|
|
252
|
+
{
|
|
253
|
+
String_Constant* s = ARG("$string", String_Constant);
|
|
254
|
+
sass::string str = s->value();
|
|
255
|
+
Util::ascii_str_tolower(&str);
|
|
256
|
+
|
|
257
|
+
if (String_Quoted* ss = Cast<String_Quoted>(s)) {
|
|
258
|
+
String_Quoted* cpy = SASS_MEMORY_COPY(ss);
|
|
259
|
+
cpy->value(str);
|
|
260
|
+
return cpy;
|
|
261
|
+
} else {
|
|
262
|
+
return SASS_MEMORY_NEW(String_Quoted, pstate, str);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#ifndef SASS_FN_STRINGS_H
|
|
2
|
+
#define SASS_FN_STRINGS_H
|
|
3
|
+
|
|
4
|
+
#include "fn_utils.hpp"
|
|
5
|
+
|
|
6
|
+
namespace Sass {
|
|
7
|
+
|
|
8
|
+
namespace Functions {
|
|
9
|
+
|
|
10
|
+
extern Signature unquote_sig;
|
|
11
|
+
extern Signature quote_sig;
|
|
12
|
+
extern Signature str_length_sig;
|
|
13
|
+
extern Signature str_insert_sig;
|
|
14
|
+
extern Signature str_index_sig;
|
|
15
|
+
extern Signature str_slice_sig;
|
|
16
|
+
extern Signature to_upper_case_sig;
|
|
17
|
+
extern Signature to_lower_case_sig;
|
|
18
|
+
extern Signature length_sig;
|
|
19
|
+
|
|
20
|
+
BUILT_IN(sass_unquote);
|
|
21
|
+
BUILT_IN(sass_quote);
|
|
22
|
+
BUILT_IN(str_length);
|
|
23
|
+
BUILT_IN(str_insert);
|
|
24
|
+
BUILT_IN(str_index);
|
|
25
|
+
BUILT_IN(str_slice);
|
|
26
|
+
BUILT_IN(to_upper_case);
|
|
27
|
+
BUILT_IN(to_lower_case);
|
|
28
|
+
BUILT_IN(length);
|
|
29
|
+
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
#endif
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
// sass.hpp must go before all system headers to get the
|
|
2
|
+
// __EXTENSIONS__ fix on Solaris.
|
|
3
|
+
#include "sass.hpp"
|
|
4
|
+
|
|
5
|
+
#include "parser.hpp"
|
|
6
|
+
#include "fn_utils.hpp"
|
|
7
|
+
#include "util_string.hpp"
|
|
8
|
+
|
|
9
|
+
namespace Sass {
|
|
10
|
+
|
|
11
|
+
Definition* make_native_function(Signature sig, Native_Function func, Context& ctx)
|
|
12
|
+
{
|
|
13
|
+
SourceFile* source = SASS_MEMORY_NEW(SourceFile, "[built-in function]", sig, std::string::npos);
|
|
14
|
+
Parser sig_parser(source, ctx, ctx.traces);
|
|
15
|
+
sig_parser.lex<Prelexer::identifier>();
|
|
16
|
+
sass::string name(Util::normalize_underscores(sig_parser.lexed));
|
|
17
|
+
Parameters_Obj params = sig_parser.parse_parameters();
|
|
18
|
+
return SASS_MEMORY_NEW(Definition,
|
|
19
|
+
SourceSpan(source),
|
|
20
|
+
sig,
|
|
21
|
+
name,
|
|
22
|
+
params,
|
|
23
|
+
func,
|
|
24
|
+
false);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
Definition* make_c_function(Sass_Function_Entry c_func, Context& ctx)
|
|
28
|
+
{
|
|
29
|
+
using namespace Prelexer;
|
|
30
|
+
const char* sig = sass_function_get_signature(c_func);
|
|
31
|
+
SourceFile* source = SASS_MEMORY_NEW(SourceFile, "[c function]", sig, std::string::npos);
|
|
32
|
+
Parser sig_parser(source, ctx, ctx.traces);
|
|
33
|
+
// allow to overload generic callback plus @warn, @error and @debug with custom functions
|
|
34
|
+
sig_parser.lex < alternatives < identifier, exactly <'*'>,
|
|
35
|
+
exactly < Constants::warn_kwd >,
|
|
36
|
+
exactly < Constants::error_kwd >,
|
|
37
|
+
exactly < Constants::debug_kwd >
|
|
38
|
+
> >();
|
|
39
|
+
sass::string name(Util::normalize_underscores(sig_parser.lexed));
|
|
40
|
+
Parameters_Obj params = sig_parser.parse_parameters();
|
|
41
|
+
return SASS_MEMORY_NEW(Definition,
|
|
42
|
+
SourceSpan(source),
|
|
43
|
+
sig,
|
|
44
|
+
name,
|
|
45
|
+
params,
|
|
46
|
+
c_func);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
namespace Functions {
|
|
50
|
+
|
|
51
|
+
sass::string function_name(Signature sig)
|
|
52
|
+
{
|
|
53
|
+
sass::string str(sig);
|
|
54
|
+
return str.substr(0, str.find('('));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
Map* get_arg_m(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces)
|
|
58
|
+
{
|
|
59
|
+
AST_Node* value = env[argname];
|
|
60
|
+
if (Map* map = Cast<Map>(value)) return map;
|
|
61
|
+
List* list = Cast<List>(value);
|
|
62
|
+
if (list && list->length() == 0) {
|
|
63
|
+
return SASS_MEMORY_NEW(Map, pstate, 0);
|
|
64
|
+
}
|
|
65
|
+
return get_arg<Map>(argname, env, sig, pstate, traces);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
double get_arg_r(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces, double lo, double hi)
|
|
69
|
+
{
|
|
70
|
+
Number* val = get_arg<Number>(argname, env, sig, pstate, traces);
|
|
71
|
+
Number tmpnr(val);
|
|
72
|
+
tmpnr.reduce();
|
|
73
|
+
double v = tmpnr.value();
|
|
74
|
+
if (!(lo <= v && v <= hi)) {
|
|
75
|
+
sass::ostream msg;
|
|
76
|
+
msg << "argument `" << argname << "` of `" << sig << "` must be between ";
|
|
77
|
+
msg << lo << " and " << hi;
|
|
78
|
+
error(msg.str(), pstate, traces);
|
|
79
|
+
}
|
|
80
|
+
return v;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
Number* get_arg_n(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces)
|
|
84
|
+
{
|
|
85
|
+
Number* val = get_arg<Number>(argname, env, sig, pstate, traces);
|
|
86
|
+
val = SASS_MEMORY_COPY(val);
|
|
87
|
+
val->reduce();
|
|
88
|
+
return val;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
double get_arg_val(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces)
|
|
92
|
+
{
|
|
93
|
+
Number* val = get_arg<Number>(argname, env, sig, pstate, traces);
|
|
94
|
+
Number tmpnr(val);
|
|
95
|
+
tmpnr.reduce();
|
|
96
|
+
return tmpnr.value();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
double color_num(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces)
|
|
100
|
+
{
|
|
101
|
+
Number* val = get_arg<Number>(argname, env, sig, pstate, traces);
|
|
102
|
+
Number tmpnr(val);
|
|
103
|
+
tmpnr.reduce();
|
|
104
|
+
if (tmpnr.unit() == "%") {
|
|
105
|
+
return std::min(std::max(tmpnr.value() * 255 / 100.0, 0.0), 255.0);
|
|
106
|
+
} else {
|
|
107
|
+
return std::min(std::max(tmpnr.value(), 0.0), 255.0);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
double alpha_num(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces) {
|
|
112
|
+
Number* val = get_arg<Number>(argname, env, sig, pstate, traces);
|
|
113
|
+
Number tmpnr(val);
|
|
114
|
+
tmpnr.reduce();
|
|
115
|
+
if (tmpnr.unit() == "%") {
|
|
116
|
+
// Convert percentage to 0-1 range for alpha channel
|
|
117
|
+
return std::min(std::max(tmpnr.value() / 100.0, 0.0), 1.0);
|
|
118
|
+
} else {
|
|
119
|
+
return std::min(std::max(tmpnr.value(), 0.0), 1.0);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
SelectorListObj get_arg_sels(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces, Context& ctx) {
|
|
124
|
+
ExpressionObj exp = ARG(argname, Expression);
|
|
125
|
+
if (exp->concrete_type() == Expression::NULL_VAL) {
|
|
126
|
+
sass::ostream msg;
|
|
127
|
+
msg << argname << ": null is not a valid selector: it must be a string,\n";
|
|
128
|
+
msg << "a list of strings, or a list of lists of strings for `" << function_name(sig) << "'";
|
|
129
|
+
error(msg.str(), exp->pstate(), traces);
|
|
130
|
+
}
|
|
131
|
+
if (String_Constant* str = Cast<String_Constant>(exp)) {
|
|
132
|
+
str->quote_mark(0);
|
|
133
|
+
}
|
|
134
|
+
sass::string exp_src = exp->to_string(ctx.c_options);
|
|
135
|
+
ItplFile* source = SASS_MEMORY_NEW(ItplFile, exp_src.c_str(), exp->pstate());
|
|
136
|
+
return Parser::parse_selector(source, ctx, traces, false);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
CompoundSelectorObj get_arg_sel(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces, Context& ctx) {
|
|
140
|
+
ExpressionObj exp = ARG(argname, Expression);
|
|
141
|
+
if (exp->concrete_type() == Expression::NULL_VAL) {
|
|
142
|
+
sass::ostream msg;
|
|
143
|
+
msg << argname << ": null is not a string for `" << function_name(sig) << "'";
|
|
144
|
+
error(msg.str(), exp->pstate(), traces);
|
|
145
|
+
}
|
|
146
|
+
if (String_Constant* str = Cast<String_Constant>(exp)) {
|
|
147
|
+
str->quote_mark(0);
|
|
148
|
+
}
|
|
149
|
+
sass::string exp_src = exp->to_string(ctx.c_options);
|
|
150
|
+
ItplFile* source = SASS_MEMORY_NEW(ItplFile, exp_src.c_str(), exp->pstate());
|
|
151
|
+
SelectorListObj sel_list = Parser::parse_selector(source, ctx, traces, false);
|
|
152
|
+
if (sel_list->length() == 0) return {};
|
|
153
|
+
return sel_list->first()->first();
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
}
|