sassc 2.1.0.pre3 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/CHANGELOG.md +24 -0
- data/Rakefile +2 -4
- data/ext/extconf.rb +13 -5
- data/ext/libsass/VERSION +1 -1
- data/ext/libsass/include/sass/base.h +2 -1
- data/ext/libsass/include/sass/context.h +4 -0
- data/ext/libsass/src/MurmurHash2.hpp +91 -0
- data/ext/libsass/src/ast.cpp +158 -168
- data/ext/libsass/src/ast.hpp +389 -230
- data/ext/libsass/src/ast_def_macros.hpp +18 -10
- data/ext/libsass/src/ast_fwd_decl.cpp +4 -3
- data/ext/libsass/src/ast_fwd_decl.hpp +98 -165
- data/ext/libsass/src/ast_helpers.hpp +292 -0
- data/ext/libsass/src/ast_sel_cmp.cpp +219 -732
- data/ext/libsass/src/ast_sel_super.cpp +539 -0
- data/ext/libsass/src/ast_sel_unify.cpp +207 -212
- data/ext/libsass/src/ast_sel_weave.cpp +616 -0
- data/ext/libsass/src/ast_selectors.cpp +594 -1026
- data/ext/libsass/src/ast_selectors.hpp +339 -385
- data/ext/libsass/src/ast_supports.cpp +36 -52
- data/ext/libsass/src/ast_supports.hpp +29 -29
- data/ext/libsass/src/ast_values.cpp +271 -84
- data/ext/libsass/src/ast_values.hpp +116 -107
- data/ext/libsass/src/backtrace.cpp +9 -9
- data/ext/libsass/src/backtrace.hpp +5 -5
- data/ext/libsass/src/base64vlq.cpp +2 -2
- data/ext/libsass/src/base64vlq.hpp +1 -1
- data/ext/libsass/src/bind.cpp +18 -18
- data/ext/libsass/src/bind.hpp +1 -1
- data/ext/libsass/src/c2ast.cpp +3 -3
- data/ext/libsass/src/c2ast.hpp +1 -1
- data/ext/libsass/src/cencode.c +4 -6
- data/ext/libsass/src/check_nesting.cpp +40 -41
- data/ext/libsass/src/check_nesting.hpp +6 -2
- data/ext/libsass/src/color_maps.cpp +14 -13
- data/ext/libsass/src/color_maps.hpp +1 -9
- data/ext/libsass/src/constants.cpp +5 -0
- data/ext/libsass/src/constants.hpp +6 -0
- data/ext/libsass/src/context.cpp +92 -119
- data/ext/libsass/src/context.hpp +41 -53
- data/ext/libsass/src/cssize.cpp +66 -149
- data/ext/libsass/src/cssize.hpp +17 -23
- data/ext/libsass/src/dart_helpers.hpp +199 -0
- data/ext/libsass/src/debugger.hpp +451 -295
- data/ext/libsass/src/emitter.cpp +15 -16
- data/ext/libsass/src/emitter.hpp +10 -12
- data/ext/libsass/src/environment.cpp +27 -27
- data/ext/libsass/src/environment.hpp +29 -24
- data/ext/libsass/src/error_handling.cpp +62 -41
- data/ext/libsass/src/error_handling.hpp +61 -51
- data/ext/libsass/src/eval.cpp +167 -281
- data/ext/libsass/src/eval.hpp +27 -29
- data/ext/libsass/src/eval_selectors.cpp +75 -0
- data/ext/libsass/src/expand.cpp +275 -222
- data/ext/libsass/src/expand.hpp +36 -16
- 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 +81 -72
- data/ext/libsass/src/file.hpp +28 -37
- data/ext/libsass/src/fn_colors.cpp +20 -18
- data/ext/libsass/src/fn_lists.cpp +30 -29
- data/ext/libsass/src/fn_maps.cpp +3 -3
- data/ext/libsass/src/fn_miscs.cpp +34 -46
- data/ext/libsass/src/fn_numbers.cpp +20 -13
- data/ext/libsass/src/fn_selectors.cpp +98 -128
- data/ext/libsass/src/fn_strings.cpp +47 -33
- data/ext/libsass/src/fn_utils.cpp +31 -29
- data/ext/libsass/src/fn_utils.hpp +17 -11
- data/ext/libsass/src/inspect.cpp +186 -148
- data/ext/libsass/src/inspect.hpp +31 -29
- data/ext/libsass/src/lexer.cpp +20 -82
- data/ext/libsass/src/lexer.hpp +5 -16
- data/ext/libsass/src/listize.cpp +23 -37
- data/ext/libsass/src/listize.hpp +8 -9
- data/ext/libsass/src/mapping.hpp +1 -0
- data/ext/libsass/src/memory.hpp +12 -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/{SharedPtr.cpp → shared_ptr.cpp} +2 -2
- data/ext/libsass/src/memory/{SharedPtr.hpp → shared_ptr.hpp} +55 -9
- data/ext/libsass/src/operation.hpp +71 -61
- data/ext/libsass/src/operators.cpp +19 -18
- data/ext/libsass/src/operators.hpp +11 -11
- data/ext/libsass/src/ordered_map.hpp +112 -0
- data/ext/libsass/src/output.cpp +45 -64
- data/ext/libsass/src/output.hpp +6 -6
- data/ext/libsass/src/parser.cpp +512 -700
- data/ext/libsass/src/parser.hpp +89 -97
- data/ext/libsass/src/parser_selectors.cpp +189 -0
- data/ext/libsass/src/permutate.hpp +164 -0
- data/ext/libsass/src/plugins.cpp +7 -7
- data/ext/libsass/src/plugins.hpp +8 -8
- data/ext/libsass/src/position.cpp +7 -26
- data/ext/libsass/src/position.hpp +44 -21
- data/ext/libsass/src/prelexer.cpp +6 -6
- data/ext/libsass/src/remove_placeholders.cpp +55 -56
- data/ext/libsass/src/remove_placeholders.hpp +21 -18
- data/ext/libsass/src/sass.cpp +16 -15
- data/ext/libsass/src/sass.hpp +10 -5
- data/ext/libsass/src/sass2scss.cpp +4 -4
- data/ext/libsass/src/sass_context.cpp +91 -122
- data/ext/libsass/src/sass_context.hpp +2 -2
- data/ext/libsass/src/sass_functions.cpp +1 -1
- data/ext/libsass/src/sass_values.cpp +8 -11
- 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 +22 -18
- data/ext/libsass/src/source_map.hpp +12 -9
- data/ext/libsass/src/stylesheet.cpp +22 -0
- data/ext/libsass/src/stylesheet.hpp +57 -0
- data/ext/libsass/src/to_value.cpp +2 -2
- data/ext/libsass/src/to_value.hpp +1 -1
- data/ext/libsass/src/units.cpp +24 -22
- data/ext/libsass/src/units.hpp +8 -8
- data/ext/libsass/src/utf8_string.cpp +9 -10
- data/ext/libsass/src/utf8_string.hpp +7 -6
- data/ext/libsass/src/util.cpp +48 -50
- data/ext/libsass/src/util.hpp +20 -21
- data/ext/libsass/src/util_string.cpp +111 -61
- data/ext/libsass/src/util_string.hpp +62 -8
- data/ext/libsass/src/values.cpp +12 -12
- data/lib/sassc/engine.rb +5 -3
- data/lib/sassc/functions_handler.rb +11 -13
- data/lib/sassc/native.rb +9 -7
- data/lib/sassc/script.rb +4 -6
- data/lib/sassc/version.rb +1 -1
- data/test/functions_test.rb +38 -1
- data/test/native_test.rb +4 -4
- metadata +31 -18
- data/ext/libsass/src/extend.cpp +0 -2132
- data/ext/libsass/src/extend.hpp +0 -86
- data/ext/libsass/src/node.cpp +0 -322
- data/ext/libsass/src/node.hpp +0 -118
- data/ext/libsass/src/paths.hpp +0 -71
- data/ext/libsass/src/sass_util.cpp +0 -152
- data/ext/libsass/src/sass_util.hpp +0 -256
- data/ext/libsass/src/subset_map.cpp +0 -58
- data/ext/libsass/src/subset_map.hpp +0 -76
- data/lib/sassc/native/lib_c.rb +0 -21
@@ -5,7 +5,6 @@
|
|
5
5
|
#include <cstdint>
|
6
6
|
#include <cstdlib>
|
7
7
|
#include <cmath>
|
8
|
-
#include <cctype>
|
9
8
|
#include <random>
|
10
9
|
#include <sstream>
|
11
10
|
#include <iomanip>
|
@@ -61,7 +60,7 @@ namespace Sass {
|
|
61
60
|
BUILT_IN(percentage)
|
62
61
|
{
|
63
62
|
Number_Obj n = ARGN("$number");
|
64
|
-
if (!n->is_unitless()) error("argument $number of `" +
|
63
|
+
if (!n->is_unitless()) error("argument $number of `" + sass::string(sig) + "` must be unitless", pstate, traces);
|
65
64
|
return SASS_MEMORY_NEW(Number, pstate, n->value() * 100, "%");
|
66
65
|
}
|
67
66
|
|
@@ -106,8 +105,12 @@ namespace Sass {
|
|
106
105
|
{
|
107
106
|
List* arglist = ARG("$numbers", List);
|
108
107
|
Number_Obj least;
|
109
|
-
|
110
|
-
|
108
|
+
size_t L = arglist->length();
|
109
|
+
if (L == 0) {
|
110
|
+
error("At least one argument must be passed.", pstate, traces);
|
111
|
+
}
|
112
|
+
for (size_t i = 0; i < L; ++i) {
|
113
|
+
ExpressionObj val = arglist->value_at_index(i);
|
111
114
|
Number_Obj xi = Cast<Number>(val);
|
112
115
|
if (!xi) {
|
113
116
|
error("\"" + val->to_string(ctx.c_options) + "\" is not a number for `min'", pstate, traces);
|
@@ -124,8 +127,12 @@ namespace Sass {
|
|
124
127
|
{
|
125
128
|
List* arglist = ARG("$numbers", List);
|
126
129
|
Number_Obj greatest;
|
127
|
-
|
128
|
-
|
130
|
+
size_t L = arglist->length();
|
131
|
+
if (L == 0) {
|
132
|
+
error("At least one argument must be passed.", pstate, traces);
|
133
|
+
}
|
134
|
+
for (size_t i = 0; i < L; ++i) {
|
135
|
+
ExpressionObj val = arglist->value_at_index(i);
|
129
136
|
Number_Obj xi = Cast<Number>(val);
|
130
137
|
if (!xi) {
|
131
138
|
error("\"" + val->to_string(ctx.c_options) + "\" is not a number for `max'", pstate, traces);
|
@@ -147,13 +154,13 @@ namespace Sass {
|
|
147
154
|
if (l) {
|
148
155
|
double lv = l->value();
|
149
156
|
if (lv < 1) {
|
150
|
-
|
157
|
+
sass::ostream err;
|
151
158
|
err << "$limit " << lv << " must be greater than or equal to 1 for `random'";
|
152
159
|
error(err.str(), pstate, traces);
|
153
160
|
}
|
154
161
|
bool eq_int = std::fabs(trunc(lv) - lv) < NUMBER_EPSILON;
|
155
162
|
if (!eq_int) {
|
156
|
-
|
163
|
+
sass::ostream err;
|
157
164
|
err << "Expected $limit to be an integer but got " << lv << " for `random'";
|
158
165
|
error(err.str(), pstate, traces);
|
159
166
|
}
|
@@ -177,7 +184,7 @@ namespace Sass {
|
|
177
184
|
Signature unique_id_sig = "unique-id()";
|
178
185
|
BUILT_IN(unique_id)
|
179
186
|
{
|
180
|
-
|
187
|
+
sass::ostream ss;
|
181
188
|
std::uniform_real_distribution<> distributor(0, 4294967296); // 16^8
|
182
189
|
uint_fast32_t distributed = static_cast<uint_fast32_t>(distributor(rand));
|
183
190
|
ss << "u" << std::setfill('0') << std::setw(8) << std::hex << distributed;
|
@@ -188,7 +195,7 @@ namespace Sass {
|
|
188
195
|
BUILT_IN(unit)
|
189
196
|
{
|
190
197
|
Number_Obj arg = ARGN("$number");
|
191
|
-
|
198
|
+
sass::string str(quote(arg->unit(), '"'));
|
192
199
|
return SASS_MEMORY_NEW(String_Quoted, pstate, str);
|
193
200
|
}
|
194
201
|
|
@@ -200,11 +207,11 @@ namespace Sass {
|
|
200
207
|
return SASS_MEMORY_NEW(Boolean, pstate, unitless);
|
201
208
|
}
|
202
209
|
|
203
|
-
Signature comparable_sig = "comparable($
|
210
|
+
Signature comparable_sig = "comparable($number1, $number2)";
|
204
211
|
BUILT_IN(comparable)
|
205
212
|
{
|
206
|
-
Number_Obj n1 = ARGN("$
|
207
|
-
Number_Obj n2 = ARGN("$
|
213
|
+
Number_Obj n1 = ARGN("$number1");
|
214
|
+
Number_Obj n2 = ARGN("$number2");
|
208
215
|
if (n1->is_unitless() || n2->is_unitless()) {
|
209
216
|
return SASS_MEMORY_NEW(Boolean, pstate, true);
|
210
217
|
}
|
@@ -1,5 +1,8 @@
|
|
1
|
+
#include <numeric>
|
2
|
+
|
1
3
|
#include "parser.hpp"
|
2
|
-
#include "
|
4
|
+
#include "extender.hpp"
|
5
|
+
#include "listize.hpp"
|
3
6
|
#include "fn_utils.hpp"
|
4
7
|
#include "fn_selectors.hpp"
|
5
8
|
|
@@ -13,24 +16,28 @@ namespace Sass {
|
|
13
16
|
List* arglist = ARG("$selectors", List);
|
14
17
|
|
15
18
|
// Not enough parameters
|
16
|
-
if(
|
17
|
-
error(
|
19
|
+
if (arglist->length() == 0) {
|
20
|
+
error(
|
21
|
+
"$selectors: At least one selector must be passed for `selector-nest'",
|
22
|
+
pstate, traces);
|
23
|
+
}
|
18
24
|
|
19
25
|
// Parse args into vector of selectors
|
20
26
|
SelectorStack parsedSelectors;
|
21
27
|
for (size_t i = 0, L = arglist->length(); i < L; ++i) {
|
22
|
-
|
28
|
+
ExpressionObj exp = Cast<Expression>(arglist->value_at_index(i));
|
23
29
|
if (exp->concrete_type() == Expression::NULL_VAL) {
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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);
|
28
34
|
}
|
29
35
|
if (String_Constant_Obj str = Cast<String_Constant>(exp)) {
|
30
36
|
str->quote_mark(0);
|
31
37
|
}
|
32
|
-
|
33
|
-
|
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);
|
34
41
|
parsedSelectors.push_back(sel);
|
35
42
|
}
|
36
43
|
|
@@ -39,25 +46,21 @@ namespace Sass {
|
|
39
46
|
return SASS_MEMORY_NEW(Null, pstate);
|
40
47
|
}
|
41
48
|
|
42
|
-
// Set the first element as the `result`, keep
|
49
|
+
// Set the first element as the `result`, keep
|
50
|
+
// appending to as we go down the parsedSelector vector.
|
43
51
|
SelectorStack::iterator itr = parsedSelectors.begin();
|
44
|
-
|
52
|
+
SelectorListObj& result = *itr;
|
45
53
|
++itr;
|
46
54
|
|
47
55
|
for(;itr != parsedSelectors.end(); ++itr) {
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
for (size_t m = 0, mLen = rv->length(); m < mLen; ++m) {
|
54
|
-
exploded.push_back((*rv)[m]);
|
55
|
-
}
|
56
|
-
result->elements(exploded);
|
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();
|
57
61
|
}
|
58
62
|
|
59
|
-
Listize
|
60
|
-
return Cast<Value>(result->perform(&listize));
|
63
|
+
return Cast<Value>(Listize::perform(result));
|
61
64
|
}
|
62
65
|
|
63
66
|
Signature selector_append_sig = "selector-append($selectors...)";
|
@@ -66,113 +69,95 @@ namespace Sass {
|
|
66
69
|
List* arglist = ARG("$selectors", List);
|
67
70
|
|
68
71
|
// Not enough parameters
|
69
|
-
if(
|
70
|
-
error(
|
72
|
+
if (arglist->empty()) {
|
73
|
+
error(
|
74
|
+
"$selectors: At least one selector must be "
|
75
|
+
"passed for `selector-append'",
|
76
|
+
pstate, traces);
|
77
|
+
}
|
71
78
|
|
72
79
|
// Parse args into vector of selectors
|
73
80
|
SelectorStack parsedSelectors;
|
81
|
+
parsedSelectors.push_back({});
|
74
82
|
for (size_t i = 0, L = arglist->length(); i < L; ++i) {
|
75
|
-
|
83
|
+
Expression* exp = Cast<Expression>(arglist->value_at_index(i));
|
76
84
|
if (exp->concrete_type() == Expression::NULL_VAL) {
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
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);
|
81
89
|
}
|
82
90
|
if (String_Constant* str = Cast<String_Constant>(exp)) {
|
83
91
|
str->quote_mark(0);
|
84
92
|
}
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
/*allow_parent=*/false);
|
89
|
-
|
90
|
-
parsedSelectors.push_back(sel);
|
91
|
-
}
|
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);
|
92
96
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
for(;itr != parsedSelectors.end(); ++itr) {
|
104
|
-
Selector_List_Obj child = *itr;
|
105
|
-
std::vector<Complex_Selector_Obj> newElements;
|
106
|
-
|
107
|
-
// For every COMPLEX_SELECTOR in `result`
|
108
|
-
// For every COMPLEX_SELECTOR in `child`
|
109
|
-
// let parentSeqClone equal a copy of result->elements[i]
|
110
|
-
// let childSeq equal child->elements[j]
|
111
|
-
// Append all of childSeq head elements into parentSeqClone
|
112
|
-
// Set the innermost tail of parentSeqClone, to childSeq's tail
|
113
|
-
// Replace result->elements with newElements
|
114
|
-
for (size_t i = 0, resultLen = result->length(); i < resultLen; ++i) {
|
115
|
-
for (size_t j = 0, childLen = child->length(); j < childLen; ++j) {
|
116
|
-
Complex_Selector_Obj parentSeqClone = SASS_MEMORY_CLONE((*result)[i]);
|
117
|
-
Complex_Selector_Obj childSeq = (*child)[j];
|
118
|
-
Complex_Selector_Obj base = childSeq->tail();
|
119
|
-
|
120
|
-
// Must be a simple sequence
|
121
|
-
if( childSeq->combinator() != Complex_Selector::Combinator::ANCESTOR_OF ) {
|
122
|
-
error("Can't append \"" + childSeq->to_string() + "\" to \"" +
|
123
|
-
parentSeqClone->to_string() + "\" for `selector-append'", pstate, traces);
|
124
|
-
}
|
125
|
-
|
126
|
-
// Cannot be a Universal selector
|
127
|
-
Type_Selector_Obj pType = Cast<Type_Selector>(childSeq->head()->first());
|
128
|
-
if(pType && pType->name() == "*") {
|
129
|
-
error("Can't append \"" + childSeq->to_string() + "\" to \"" +
|
130
|
-
parentSeqClone->to_string() + "\" for `selector-append'", pstate, traces);
|
131
|
-
}
|
97
|
+
for (auto& complex : sel->elements()) {
|
98
|
+
if (complex->empty()) {
|
99
|
+
complex->append(SASS_MEMORY_NEW(CompoundSelector, "[phony]"));
|
100
|
+
}
|
101
|
+
if (CompoundSelector* comp = Cast<CompoundSelector>(complex->first())) {
|
102
|
+
comp->hasRealParent(true);
|
103
|
+
complex->chroots(true);
|
104
|
+
}
|
105
|
+
}
|
132
106
|
|
133
|
-
|
107
|
+
if (parsedSelectors.size() > 1) {
|
134
108
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
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
|
+
}
|
139
115
|
}
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
newElements.push_back(parentSeqClone);
|
116
|
+
error("Can't append \"" + sel->to_string() + "\" to \"" +
|
117
|
+
parent->to_string() + "\" for `selector-append'",
|
118
|
+
pstate, traces);
|
144
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));
|
145
128
|
}
|
129
|
+
else {
|
130
|
+
parsedSelectors.push_back(sel);
|
131
|
+
}
|
132
|
+
}
|
146
133
|
|
147
|
-
|
134
|
+
// Nothing to do
|
135
|
+
if( parsedSelectors.empty() ) {
|
136
|
+
return SASS_MEMORY_NEW(Null, pstate);
|
148
137
|
}
|
149
138
|
|
150
|
-
Listize
|
151
|
-
return Cast<Value>(result->perform(&listize));
|
139
|
+
return Cast<Value>(Listize::perform(parsedSelectors.back()));
|
152
140
|
}
|
153
141
|
|
154
142
|
Signature selector_unify_sig = "selector-unify($selector1, $selector2)";
|
155
143
|
BUILT_IN(selector_unify)
|
156
144
|
{
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
Listize listize;
|
162
|
-
return Cast<Value>(result->perform(&listize));
|
145
|
+
SelectorListObj selector1 = ARGSELS("$selector1");
|
146
|
+
SelectorListObj selector2 = ARGSELS("$selector2");
|
147
|
+
SelectorListObj result = selector1->unifyWith(selector2);
|
148
|
+
return Cast<Value>(Listize::perform(result));
|
163
149
|
}
|
164
150
|
|
165
151
|
Signature simple_selectors_sig = "simple-selectors($selector)";
|
166
152
|
BUILT_IN(simple_selectors)
|
167
153
|
{
|
168
|
-
|
154
|
+
CompoundSelectorObj sel = ARGSEL("$selector");
|
169
155
|
|
170
156
|
List* l = SASS_MEMORY_NEW(List, sel->pstate(), sel->length(), SASS_COMMA);
|
171
157
|
|
172
158
|
for (size_t i = 0, L = sel->length(); i < L; ++i) {
|
173
|
-
|
174
|
-
|
175
|
-
|
159
|
+
const SimpleSelectorObj& ss = sel->get(i);
|
160
|
+
sass::string ss_string = ss->to_string() ;
|
176
161
|
l->append(SASS_MEMORY_NEW(String_Quoted, ss->pstate(), ss_string));
|
177
162
|
}
|
178
163
|
|
@@ -182,51 +167,36 @@ namespace Sass {
|
|
182
167
|
Signature selector_extend_sig = "selector-extend($selector, $extendee, $extender)";
|
183
168
|
BUILT_IN(selector_extend)
|
184
169
|
{
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
extender->populate_extends(extendee, subset_map);
|
191
|
-
Extend extend(subset_map);
|
192
|
-
|
193
|
-
Selector_List_Obj result = extend.extendSelectorList(selector, false);
|
194
|
-
|
195
|
-
Listize listize;
|
196
|
-
return Cast<Value>(result->perform(&listize));
|
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));
|
197
175
|
}
|
198
176
|
|
199
177
|
Signature selector_replace_sig = "selector-replace($selector, $original, $replacement)";
|
200
178
|
BUILT_IN(selector_replace)
|
201
179
|
{
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
Extend extend(subset_map);
|
208
|
-
|
209
|
-
Selector_List_Obj result = extend.extendSelectorList(selector, true);
|
210
|
-
|
211
|
-
Listize listize;
|
212
|
-
return Cast<Value>(result->perform(&listize));
|
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));
|
213
185
|
}
|
214
186
|
|
215
187
|
Signature selector_parse_sig = "selector-parse($selector)";
|
216
188
|
BUILT_IN(selector_parse)
|
217
189
|
{
|
218
|
-
|
219
|
-
|
220
|
-
Listize listize;
|
221
|
-
return Cast<Value>(sel->perform(&listize));
|
190
|
+
SelectorListObj selector = ARGSELS("$selector");
|
191
|
+
return Cast<Value>(Listize::perform(selector));
|
222
192
|
}
|
223
193
|
|
224
194
|
Signature is_superselector_sig = "is-superselector($super, $sub)";
|
225
195
|
BUILT_IN(is_superselector)
|
226
196
|
{
|
227
|
-
|
228
|
-
|
229
|
-
bool result = sel_sup->
|
197
|
+
SelectorListObj sel_sup = ARGSELS("$super");
|
198
|
+
SelectorListObj sel_sub = ARGSELS("$sub");
|
199
|
+
bool result = sel_sup->isSuperselectorOf(sel_sub);
|
230
200
|
return SASS_MEMORY_NEW(Boolean, pstate, result);
|
231
201
|
}
|
232
202
|
|
@@ -2,31 +2,31 @@
|
|
2
2
|
// __EXTENSIONS__ fix on Solaris.
|
3
3
|
#include "sass.hpp"
|
4
4
|
|
5
|
-
#include <cctype>
|
6
5
|
#include "utf8.h"
|
7
6
|
#include "ast.hpp"
|
8
7
|
#include "fn_utils.hpp"
|
9
8
|
#include "fn_strings.hpp"
|
9
|
+
#include "util_string.hpp"
|
10
10
|
|
11
11
|
namespace Sass {
|
12
12
|
|
13
13
|
namespace Functions {
|
14
14
|
|
15
|
-
void handle_utf8_error (const
|
15
|
+
void handle_utf8_error (const SourceSpan& pstate, Backtraces traces)
|
16
16
|
{
|
17
17
|
try {
|
18
18
|
throw;
|
19
19
|
}
|
20
20
|
catch (utf8::invalid_code_point&) {
|
21
|
-
|
21
|
+
sass::string msg("utf8::invalid_code_point");
|
22
22
|
error(msg, pstate, traces);
|
23
23
|
}
|
24
24
|
catch (utf8::not_enough_room&) {
|
25
|
-
|
25
|
+
sass::string msg("utf8::not_enough_room");
|
26
26
|
error(msg, pstate, traces);
|
27
27
|
}
|
28
28
|
catch (utf8::invalid_utf8&) {
|
29
|
-
|
29
|
+
sass::string msg("utf8::invalid_utf8");
|
30
30
|
error(msg, pstate, traces);
|
31
31
|
}
|
32
32
|
catch (...) { throw; }
|
@@ -52,7 +52,7 @@ namespace Sass {
|
|
52
52
|
else if (Value* ex = Cast<Value>(arg)) {
|
53
53
|
Sass_Output_Style oldstyle = ctx.c_options.output_style;
|
54
54
|
ctx.c_options.output_style = SASS_STYLE_NESTED;
|
55
|
-
|
55
|
+
sass::string val(arg->to_string(ctx.c_options));
|
56
56
|
val = Cast<Null>(arg) ? "null" : val;
|
57
57
|
ctx.c_options.output_style = oldstyle;
|
58
58
|
|
@@ -76,7 +76,7 @@ namespace Sass {
|
|
76
76
|
Signature str_length_sig = "str-length($string)";
|
77
77
|
BUILT_IN(str_length)
|
78
78
|
{
|
79
|
-
size_t len =
|
79
|
+
size_t len = sass::string::npos;
|
80
80
|
try {
|
81
81
|
String_Constant* s = ARG("$string", String_Constant);
|
82
82
|
len = UTF_8::code_point_count(s->value(), 0, s->value().size());
|
@@ -92,13 +92,20 @@ namespace Sass {
|
|
92
92
|
Signature str_insert_sig = "str-insert($string, $insert, $index)";
|
93
93
|
BUILT_IN(str_insert)
|
94
94
|
{
|
95
|
-
|
95
|
+
sass::string str;
|
96
96
|
try {
|
97
97
|
String_Constant* s = ARG("$string", String_Constant);
|
98
98
|
str = s->value();
|
99
99
|
String_Constant* i = ARG("$insert", String_Constant);
|
100
|
-
|
100
|
+
sass::string ins = i->value();
|
101
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
|
+
}
|
102
109
|
size_t len = UTF_8::code_point_count(str, 0, str.size());
|
103
110
|
|
104
111
|
if (index > 0 && index <= len) {
|
@@ -135,15 +142,15 @@ namespace Sass {
|
|
135
142
|
Signature str_index_sig = "str-index($string, $substring)";
|
136
143
|
BUILT_IN(str_index)
|
137
144
|
{
|
138
|
-
size_t index =
|
145
|
+
size_t index = sass::string::npos;
|
139
146
|
try {
|
140
147
|
String_Constant* s = ARG("$string", String_Constant);
|
141
148
|
String_Constant* t = ARG("$substring", String_Constant);
|
142
|
-
|
143
|
-
|
149
|
+
sass::string str = s->value();
|
150
|
+
sass::string substr = t->value();
|
144
151
|
|
145
152
|
size_t c_index = str.find(substr);
|
146
|
-
if(c_index ==
|
153
|
+
if(c_index == sass::string::npos) {
|
147
154
|
return SASS_MEMORY_NEW(Null, pstate);
|
148
155
|
}
|
149
156
|
index = UTF_8::code_point_count(str, 0, c_index) + 1;
|
@@ -158,14 +165,23 @@ namespace Sass {
|
|
158
165
|
Signature str_slice_sig = "str-slice($string, $start-at, $end-at:-1)";
|
159
166
|
BUILT_IN(str_slice)
|
160
167
|
{
|
161
|
-
|
168
|
+
sass::string newstr;
|
162
169
|
try {
|
163
170
|
String_Constant* s = ARG("$string", String_Constant);
|
164
171
|
double start_at = ARGVAL("$start-at");
|
165
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
|
+
|
166
182
|
String_Quoted* ss = Cast<String_Quoted>(s);
|
167
183
|
|
168
|
-
|
184
|
+
sass::string str(s->value());
|
169
185
|
|
170
186
|
size_t size = utf8::distance(str.begin(), str.end());
|
171
187
|
|
@@ -173,6 +189,14 @@ namespace Sass {
|
|
173
189
|
end_at = -1;
|
174
190
|
}
|
175
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
|
+
|
176
200
|
if (end_at == 0 || (end_at + size) < 0) {
|
177
201
|
if (ss && ss->quote_mark()) newstr = quote("");
|
178
202
|
return SASS_MEMORY_NEW(String_Quoted, pstate, newstr);
|
@@ -185,17 +209,17 @@ namespace Sass {
|
|
185
209
|
if (end_at > size) { end_at = (double)size; }
|
186
210
|
if (start_at < 0) {
|
187
211
|
start_at += size + 1;
|
188
|
-
if (start_at
|
212
|
+
if (start_at <= 0) start_at = 1;
|
189
213
|
}
|
190
214
|
else if (start_at == 0) { ++ start_at; }
|
191
215
|
|
192
216
|
if (start_at <= end_at)
|
193
217
|
{
|
194
|
-
|
218
|
+
sass::string::iterator start = str.begin();
|
195
219
|
utf8::advance(start, start_at - 1, str.end());
|
196
|
-
|
220
|
+
sass::string::iterator end = start;
|
197
221
|
utf8::advance(end, end_at - start_at + 1, str.end());
|
198
|
-
newstr =
|
222
|
+
newstr = sass::string(start, end);
|
199
223
|
}
|
200
224
|
if (ss) {
|
201
225
|
if(ss->quote_mark()) newstr = quote(newstr);
|
@@ -211,13 +235,8 @@ namespace Sass {
|
|
211
235
|
BUILT_IN(to_upper_case)
|
212
236
|
{
|
213
237
|
String_Constant* s = ARG("$string", String_Constant);
|
214
|
-
|
215
|
-
|
216
|
-
for (size_t i = 0, L = str.length(); i < L; ++i) {
|
217
|
-
if (Sass::Util::isAscii(str[i])) {
|
218
|
-
str[i] = std::toupper(str[i]);
|
219
|
-
}
|
220
|
-
}
|
238
|
+
sass::string str = s->value();
|
239
|
+
Util::ascii_str_toupper(&str);
|
221
240
|
|
222
241
|
if (String_Quoted* ss = Cast<String_Quoted>(s)) {
|
223
242
|
String_Quoted* cpy = SASS_MEMORY_COPY(ss);
|
@@ -232,13 +251,8 @@ namespace Sass {
|
|
232
251
|
BUILT_IN(to_lower_case)
|
233
252
|
{
|
234
253
|
String_Constant* s = ARG("$string", String_Constant);
|
235
|
-
|
236
|
-
|
237
|
-
for (size_t i = 0, L = str.length(); i < L; ++i) {
|
238
|
-
if (Sass::Util::isAscii(str[i])) {
|
239
|
-
str[i] = std::tolower(str[i]);
|
240
|
-
}
|
241
|
-
}
|
254
|
+
sass::string str = s->value();
|
255
|
+
Util::ascii_str_tolower(&str);
|
242
256
|
|
243
257
|
if (String_Quoted* ss = Cast<String_Quoted>(s)) {
|
244
258
|
String_Quoted* cpy = SASS_MEMORY_COPY(ss);
|