sassc 1.11.4 → 1.12.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 +5 -5
- data/.travis.yml +2 -2
- data/CODE_OF_CONDUCT.md +10 -0
- data/README.md +4 -1
- data/ext/libsass/.editorconfig +1 -1
- data/ext/libsass/.github/CONTRIBUTING.md +7 -7
- data/ext/libsass/.github/ISSUE_TEMPLATE.md +31 -6
- data/ext/libsass/.gitignore +3 -0
- data/ext/libsass/.travis.yml +37 -18
- data/ext/libsass/GNUmakefile.am +23 -37
- data/ext/libsass/Makefile +10 -6
- data/ext/libsass/Makefile.conf +3 -0
- data/ext/libsass/Readme.md +68 -63
- data/ext/libsass/appveyor.yml +7 -3
- data/ext/libsass/configure.ac +10 -14
- data/ext/libsass/docs/api-context-internal.md +29 -21
- data/ext/libsass/docs/api-context.md +26 -6
- data/ext/libsass/docs/api-doc.md +49 -16
- data/ext/libsass/docs/api-function-example.md +1 -1
- data/ext/libsass/docs/api-function.md +31 -7
- data/ext/libsass/docs/api-importer.md +19 -19
- data/ext/libsass/docs/api-value.md +4 -2
- data/ext/libsass/docs/build-on-windows.md +4 -4
- data/ext/libsass/docs/build-with-mingw.md +3 -3
- data/ext/libsass/docs/build.md +9 -9
- data/ext/libsass/docs/custom-functions-internal.md +10 -8
- data/ext/libsass/docs/implementations.md +20 -8
- data/ext/libsass/docs/unicode.md +16 -10
- data/ext/libsass/include/sass/base.h +0 -3
- data/ext/libsass/include/sass/context.h +20 -2
- data/ext/libsass/include/sass/functions.h +31 -0
- data/ext/libsass/include/sass/values.h +3 -1
- data/ext/libsass/include/sass/version.h +1 -1
- data/ext/libsass/include/sass/version.h.in +1 -1
- data/ext/libsass/include/sass2scss.h +1 -1
- data/ext/libsass/res/resource.rc +6 -6
- data/ext/libsass/script/ci-build-libsass +10 -5
- data/ext/libsass/script/ci-build-plugin +62 -0
- data/ext/libsass/script/ci-install-compiler +1 -1
- data/ext/libsass/script/ci-install-deps +4 -7
- data/ext/libsass/script/ci-report-coverage +13 -3
- data/ext/libsass/script/tap-driver +1 -1
- data/ext/libsass/script/tap-runner +1 -1
- data/ext/libsass/src/GNUmakefile.am +1 -1
- data/ext/libsass/src/ast.cpp +537 -762
- data/ext/libsass/src/ast.hpp +377 -419
- data/ext/libsass/src/ast_def_macros.hpp +26 -1
- data/ext/libsass/src/ast_fwd_decl.cpp +29 -0
- data/ext/libsass/src/ast_fwd_decl.hpp +94 -21
- data/ext/libsass/src/b64/encode.h +3 -1
- data/ext/libsass/src/backtrace.cpp +46 -0
- data/ext/libsass/src/backtrace.hpp +7 -54
- data/ext/libsass/src/bind.cpp +72 -50
- data/ext/libsass/src/bind.hpp +0 -1
- data/ext/libsass/src/cencode.c +6 -0
- data/ext/libsass/src/check_nesting.cpp +157 -135
- data/ext/libsass/src/check_nesting.hpp +11 -10
- data/ext/libsass/src/color_maps.cpp +10 -6
- data/ext/libsass/src/color_maps.hpp +6 -8
- data/ext/libsass/src/constants.cpp +4 -3
- data/ext/libsass/src/constants.hpp +4 -3
- data/ext/libsass/src/context.cpp +110 -47
- data/ext/libsass/src/context.hpp +11 -1
- data/ext/libsass/src/cssize.cpp +105 -94
- data/ext/libsass/src/cssize.hpp +4 -5
- data/ext/libsass/src/debugger.hpp +247 -244
- data/ext/libsass/src/emitter.cpp +30 -6
- data/ext/libsass/src/emitter.hpp +7 -0
- data/ext/libsass/src/environment.cpp +67 -16
- data/ext/libsass/src/environment.hpp +28 -7
- data/ext/libsass/src/error_handling.cpp +92 -64
- data/ext/libsass/src/error_handling.hpp +64 -43
- data/ext/libsass/src/eval.cpp +494 -544
- data/ext/libsass/src/eval.hpp +17 -23
- data/ext/libsass/src/expand.cpp +182 -154
- data/ext/libsass/src/expand.hpp +4 -5
- data/ext/libsass/src/extend.cpp +299 -291
- data/ext/libsass/src/extend.hpp +46 -11
- data/ext/libsass/src/file.cpp +103 -36
- data/ext/libsass/src/file.hpp +21 -4
- data/ext/libsass/src/functions.cpp +561 -312
- data/ext/libsass/src/functions.hpp +8 -5
- data/ext/libsass/src/inspect.cpp +108 -53
- data/ext/libsass/src/inspect.hpp +5 -2
- data/ext/libsass/src/lexer.cpp +15 -7
- data/ext/libsass/src/lexer.hpp +13 -4
- data/ext/libsass/src/listize.cpp +3 -2
- data/ext/libsass/src/listize.hpp +0 -1
- data/ext/libsass/src/memory/SharedPtr.cpp +16 -18
- data/ext/libsass/src/memory/SharedPtr.hpp +47 -43
- data/ext/libsass/src/node.cpp +34 -38
- data/ext/libsass/src/node.hpp +6 -8
- data/ext/libsass/src/operation.hpp +2 -2
- data/ext/libsass/src/operators.cpp +240 -0
- data/ext/libsass/src/operators.hpp +30 -0
- data/ext/libsass/src/output.cpp +22 -20
- data/ext/libsass/src/parser.cpp +719 -358
- data/ext/libsass/src/parser.hpp +57 -22
- data/ext/libsass/src/plugins.cpp +28 -10
- data/ext/libsass/src/position.cpp +21 -3
- data/ext/libsass/src/position.hpp +2 -1
- data/ext/libsass/src/prelexer.cpp +104 -19
- data/ext/libsass/src/prelexer.hpp +10 -3
- data/ext/libsass/src/remove_placeholders.cpp +9 -10
- data/ext/libsass/src/remove_placeholders.hpp +1 -5
- data/ext/libsass/src/sass.cpp +62 -4
- data/ext/libsass/src/sass.hpp +5 -2
- data/ext/libsass/src/sass_context.cpp +96 -58
- data/ext/libsass/src/sass_context.hpp +7 -5
- data/ext/libsass/src/sass_functions.cpp +63 -1
- data/ext/libsass/src/sass_functions.hpp +19 -1
- data/ext/libsass/src/sass_util.cpp +3 -3
- data/ext/libsass/src/sass_util.hpp +4 -4
- data/ext/libsass/src/sass_values.cpp +42 -39
- data/ext/libsass/src/sass_values.hpp +2 -1
- data/ext/libsass/src/source_map.cpp +16 -18
- data/ext/libsass/src/subset_map.cpp +6 -8
- data/ext/libsass/src/subset_map.hpp +6 -6
- data/ext/libsass/src/to_c.cpp +2 -2
- data/ext/libsass/src/to_value.cpp +8 -3
- data/ext/libsass/src/to_value.hpp +1 -0
- data/ext/libsass/src/units.cpp +349 -45
- data/ext/libsass/src/units.hpp +39 -22
- data/ext/libsass/src/utf8/checked.h +7 -0
- data/ext/libsass/src/utf8/unchecked.h +7 -0
- data/ext/libsass/src/utf8_string.cpp +1 -1
- data/ext/libsass/src/util.cpp +139 -45
- data/ext/libsass/src/util.hpp +4 -7
- data/ext/libsass/src/values.cpp +15 -23
- data/ext/libsass/win/libsass.sln +13 -2
- data/ext/libsass/win/libsass.sln.DotSettings +9 -0
- data/ext/libsass/win/libsass.targets +3 -0
- data/ext/libsass/win/libsass.vcxproj.filters +9 -0
- data/lib/sassc/version.rb +1 -1
- data/sassc.gemspec +1 -1
- data/test/native_test.rb +1 -1
- metadata +11 -4
data/ext/libsass/src/node.hpp
CHANGED
|
@@ -61,15 +61,15 @@ namespace Sass {
|
|
|
61
61
|
static Node createCombinator(const Complex_Selector::Combinator& combinator);
|
|
62
62
|
|
|
63
63
|
// This method will klone the selector, stripping off the tail and combinator
|
|
64
|
-
static Node createSelector(
|
|
64
|
+
static Node createSelector(const Complex_Selector& pSelector);
|
|
65
65
|
|
|
66
66
|
static Node createCollection();
|
|
67
67
|
static Node createCollection(const NodeDeque& values);
|
|
68
68
|
|
|
69
69
|
static Node createNil();
|
|
70
|
-
static Node naiveTrim(Node& seqses
|
|
70
|
+
static Node naiveTrim(Node& seqses);
|
|
71
71
|
|
|
72
|
-
Node klone(
|
|
72
|
+
Node klone() const;
|
|
73
73
|
|
|
74
74
|
bool operator==(const Node& rhs) const;
|
|
75
75
|
inline bool operator!=(const Node& rhs) const { return !(*this == rhs); }
|
|
@@ -91,7 +91,7 @@ namespace Sass {
|
|
|
91
91
|
// potentialChild must be a node collection of selectors/combinators. this must be a collection
|
|
92
92
|
// of collections of nodes/combinators. This method checks if potentialChild is a child of this
|
|
93
93
|
// Node.
|
|
94
|
-
bool contains(const Node& potentialChild
|
|
94
|
+
bool contains(const Node& potentialChild) const;
|
|
95
95
|
|
|
96
96
|
private:
|
|
97
97
|
// Private constructor; Use the static methods (like createCombinator and createSelector)
|
|
@@ -110,10 +110,8 @@ namespace Sass {
|
|
|
110
110
|
#ifdef DEBUG
|
|
111
111
|
std::ostream& operator<<(std::ostream& os, const Node& node);
|
|
112
112
|
#endif
|
|
113
|
-
Node complexSelectorToNode(Complex_Selector_Ptr pToConvert
|
|
114
|
-
Complex_Selector_Ptr nodeToComplexSelector(const Node& toConvert
|
|
115
|
-
|
|
116
|
-
bool nodesEqual(const Node& one, const Node& two, bool simpleSelectorOrderDependent);
|
|
113
|
+
Node complexSelectorToNode(Complex_Selector_Ptr pToConvert);
|
|
114
|
+
Complex_Selector_Ptr nodeToComplexSelector(const Node& toConvert);
|
|
117
115
|
|
|
118
116
|
}
|
|
119
117
|
|
|
@@ -40,6 +40,7 @@ namespace Sass {
|
|
|
40
40
|
// expressions
|
|
41
41
|
virtual T operator()(List_Ptr x) = 0;
|
|
42
42
|
virtual T operator()(Map_Ptr x) = 0;
|
|
43
|
+
virtual T operator()(Function_Ptr x) = 0;
|
|
43
44
|
virtual T operator()(Binary_Expression_Ptr x) = 0;
|
|
44
45
|
virtual T operator()(Unary_Expression_Ptr x) = 0;
|
|
45
46
|
virtual T operator()(Function_Call_Ptr x) = 0;
|
|
@@ -47,7 +48,6 @@ namespace Sass {
|
|
|
47
48
|
virtual T operator()(Custom_Warning_Ptr x) = 0;
|
|
48
49
|
virtual T operator()(Custom_Error_Ptr x) = 0;
|
|
49
50
|
virtual T operator()(Variable_Ptr x) = 0;
|
|
50
|
-
virtual T operator()(Textual_Ptr x) = 0;
|
|
51
51
|
virtual T operator()(Number_Ptr x) = 0;
|
|
52
52
|
virtual T operator()(Color_Ptr x) = 0;
|
|
53
53
|
virtual T operator()(Boolean_Ptr x) = 0;
|
|
@@ -122,6 +122,7 @@ namespace Sass {
|
|
|
122
122
|
// expressions
|
|
123
123
|
T operator()(List_Ptr x) { return static_cast<D*>(this)->fallback(x); }
|
|
124
124
|
T operator()(Map_Ptr x) { return static_cast<D*>(this)->fallback(x); }
|
|
125
|
+
T operator()(Function_Ptr x) { return static_cast<D*>(this)->fallback(x); }
|
|
125
126
|
T operator()(Binary_Expression_Ptr x) { return static_cast<D*>(this)->fallback(x); }
|
|
126
127
|
T operator()(Unary_Expression_Ptr x) { return static_cast<D*>(this)->fallback(x); }
|
|
127
128
|
T operator()(Function_Call_Ptr x) { return static_cast<D*>(this)->fallback(x); }
|
|
@@ -129,7 +130,6 @@ namespace Sass {
|
|
|
129
130
|
T operator()(Custom_Warning_Ptr x) { return static_cast<D*>(this)->fallback(x); }
|
|
130
131
|
T operator()(Custom_Error_Ptr x) { return static_cast<D*>(this)->fallback(x); }
|
|
131
132
|
T operator()(Variable_Ptr x) { return static_cast<D*>(this)->fallback(x); }
|
|
132
|
-
T operator()(Textual_Ptr x) { return static_cast<D*>(this)->fallback(x); }
|
|
133
133
|
T operator()(Number_Ptr x) { return static_cast<D*>(this)->fallback(x); }
|
|
134
134
|
T operator()(Color_Ptr x) { return static_cast<D*>(this)->fallback(x); }
|
|
135
135
|
T operator()(Boolean_Ptr x) { return static_cast<D*>(this)->fallback(x); }
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
#include "sass.hpp"
|
|
2
|
+
#include "operators.hpp"
|
|
3
|
+
|
|
4
|
+
namespace Sass {
|
|
5
|
+
|
|
6
|
+
namespace Operators {
|
|
7
|
+
|
|
8
|
+
inline double add(double x, double y) { return x + y; }
|
|
9
|
+
inline double sub(double x, double y) { return x - y; }
|
|
10
|
+
inline double mul(double x, double y) { return x * y; }
|
|
11
|
+
inline double div(double x, double y) { return x / y; } // x/0 checked by caller
|
|
12
|
+
|
|
13
|
+
inline double mod(double x, double y) { // x/0 checked by caller
|
|
14
|
+
if ((x > 0 && y < 0) || (x < 0 && y > 0)) {
|
|
15
|
+
double ret = std::fmod(x, y);
|
|
16
|
+
return ret ? ret + y : ret;
|
|
17
|
+
} else {
|
|
18
|
+
return std::fmod(x, y);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
typedef double (*bop)(double, double);
|
|
23
|
+
bop ops[Sass_OP::NUM_OPS] = {
|
|
24
|
+
0, 0, // and, or
|
|
25
|
+
0, 0, 0, 0, 0, 0, // eq, neq, gt, gte, lt, lte
|
|
26
|
+
add, sub, mul, div, mod
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/* static function, has no pstate or traces */
|
|
30
|
+
bool eq(Expression_Obj lhs, Expression_Obj rhs)
|
|
31
|
+
{
|
|
32
|
+
// operation is undefined if one is not a number
|
|
33
|
+
if (!lhs || !rhs) throw Exception::UndefinedOperation(lhs, rhs, Sass_OP::EQ);
|
|
34
|
+
// use compare operator from ast node
|
|
35
|
+
return *lhs == *rhs;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/* static function, throws OperationError, has no pstate or traces */
|
|
39
|
+
bool cmp(Expression_Obj lhs, Expression_Obj rhs, const Sass_OP op)
|
|
40
|
+
{
|
|
41
|
+
// can only compare numbers!?
|
|
42
|
+
Number_Obj l = Cast<Number>(lhs);
|
|
43
|
+
Number_Obj r = Cast<Number>(rhs);
|
|
44
|
+
// operation is undefined if one is not a number
|
|
45
|
+
if (!l || !r) throw Exception::UndefinedOperation(lhs, rhs, op);
|
|
46
|
+
// use compare operator from ast node
|
|
47
|
+
return *l < *r;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* static functions, throws OperationError, has no pstate or traces */
|
|
51
|
+
bool lt(Expression_Obj lhs, Expression_Obj rhs) { return cmp(lhs, rhs, Sass_OP::LT); }
|
|
52
|
+
bool neq(Expression_Obj lhs, Expression_Obj rhs) { return eq(lhs, rhs) == false; }
|
|
53
|
+
bool gt(Expression_Obj lhs, Expression_Obj rhs) { return !cmp(lhs, rhs, Sass_OP::GT) && neq(lhs, rhs); }
|
|
54
|
+
bool lte(Expression_Obj lhs, Expression_Obj rhs) { return cmp(lhs, rhs, Sass_OP::LTE) || eq(lhs, rhs); }
|
|
55
|
+
bool gte(Expression_Obj lhs, Expression_Obj rhs) { return !cmp(lhs, rhs, Sass_OP::GTE) || eq(lhs, rhs); }
|
|
56
|
+
|
|
57
|
+
/* static function, throws OperationError, has no traces but optional pstate for returned value */
|
|
58
|
+
Value_Ptr op_strings(Sass::Operand operand, Value& lhs, Value& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
|
|
59
|
+
{
|
|
60
|
+
enum Sass_OP op = operand.operand;
|
|
61
|
+
|
|
62
|
+
String_Quoted_Ptr lqstr = Cast<String_Quoted>(&lhs);
|
|
63
|
+
String_Quoted_Ptr rqstr = Cast<String_Quoted>(&rhs);
|
|
64
|
+
|
|
65
|
+
std::string lstr(lqstr ? lqstr->value() : lhs.to_string(opt));
|
|
66
|
+
std::string rstr(rqstr ? rqstr->value() : rhs.to_string(opt));
|
|
67
|
+
|
|
68
|
+
if (Cast<Null>(&lhs)) throw Exception::InvalidNullOperation(&lhs, &rhs, op);
|
|
69
|
+
if (Cast<Null>(&rhs)) throw Exception::InvalidNullOperation(&lhs, &rhs, op);
|
|
70
|
+
|
|
71
|
+
std::string sep;
|
|
72
|
+
switch (op) {
|
|
73
|
+
case Sass_OP::ADD: sep = ""; break;
|
|
74
|
+
case Sass_OP::SUB: sep = "-"; break;
|
|
75
|
+
case Sass_OP::DIV: sep = "/"; break;
|
|
76
|
+
case Sass_OP::EQ: sep = "=="; break;
|
|
77
|
+
case Sass_OP::NEQ: sep = "!="; break;
|
|
78
|
+
case Sass_OP::LT: sep = "<"; break;
|
|
79
|
+
case Sass_OP::GT: sep = ">"; break;
|
|
80
|
+
case Sass_OP::LTE: sep = "<="; break;
|
|
81
|
+
case Sass_OP::GTE: sep = ">="; break;
|
|
82
|
+
default:
|
|
83
|
+
throw Exception::UndefinedOperation(&lhs, &rhs, op);
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (op == Sass_OP::ADD) {
|
|
88
|
+
// create string that might be quoted on output (but do not unquote what we pass)
|
|
89
|
+
return SASS_MEMORY_NEW(String_Quoted, pstate, lstr + rstr, 0, false, true);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// add whitespace around operator
|
|
93
|
+
// but only if result is not delayed
|
|
94
|
+
if (sep != "" && delayed == false) {
|
|
95
|
+
if (operand.ws_before) sep = " " + sep;
|
|
96
|
+
if (operand.ws_after) sep = sep + " ";
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (op == Sass_OP::SUB || op == Sass_OP::DIV) {
|
|
100
|
+
if (lqstr && lqstr->quote_mark()) lstr = quote(lstr);
|
|
101
|
+
if (rqstr && rqstr->quote_mark()) rstr = quote(rstr);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return SASS_MEMORY_NEW(String_Constant, pstate, lstr + sep + rstr);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* static function, throws OperationError, has no traces but optional pstate for returned value */
|
|
108
|
+
Value_Ptr op_colors(enum Sass_OP op, const Color& lhs, const Color& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
|
|
109
|
+
{
|
|
110
|
+
if (lhs.a() != rhs.a()) {
|
|
111
|
+
throw Exception::AlphaChannelsNotEqual(&lhs, &rhs, op);
|
|
112
|
+
}
|
|
113
|
+
if (op == Sass_OP::DIV && (!rhs.r() || !rhs.g() || !rhs.b())) {
|
|
114
|
+
throw Exception::ZeroDivisionError(lhs, rhs);
|
|
115
|
+
}
|
|
116
|
+
return SASS_MEMORY_NEW(Color,
|
|
117
|
+
pstate,
|
|
118
|
+
ops[op](lhs.r(), rhs.r()),
|
|
119
|
+
ops[op](lhs.g(), rhs.g()),
|
|
120
|
+
ops[op](lhs.b(), rhs.b()),
|
|
121
|
+
lhs.a());
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/* static function, throws OperationError, has no traces but optional pstate for returned value */
|
|
125
|
+
Value_Ptr op_numbers(enum Sass_OP op, const Number& lhs, const Number& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
|
|
126
|
+
{
|
|
127
|
+
double lval = lhs.value();
|
|
128
|
+
double rval = rhs.value();
|
|
129
|
+
|
|
130
|
+
if (op == Sass_OP::MOD && rval == 0) {
|
|
131
|
+
return SASS_MEMORY_NEW(String_Quoted, pstate, "NaN");
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (op == Sass_OP::DIV && rval == 0) {
|
|
135
|
+
std::string result(lval ? "Infinity" : "NaN");
|
|
136
|
+
return SASS_MEMORY_NEW(String_Quoted, pstate, result);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
size_t l_n_units = lhs.numerators.size();
|
|
140
|
+
size_t l_d_units = lhs.numerators.size();
|
|
141
|
+
size_t r_n_units = rhs.denominators.size();
|
|
142
|
+
size_t r_d_units = rhs.denominators.size();
|
|
143
|
+
// optimize out the most common and simplest case
|
|
144
|
+
if (l_n_units == r_n_units && l_d_units == r_d_units) {
|
|
145
|
+
if (l_n_units + l_d_units <= 1 && r_n_units + r_d_units <= 1) {
|
|
146
|
+
if (lhs.numerators == rhs.numerators) {
|
|
147
|
+
if (lhs.denominators == rhs.denominators) {
|
|
148
|
+
Number_Ptr v = SASS_MEMORY_COPY(&lhs);
|
|
149
|
+
v->value(ops[op](lval, rval));
|
|
150
|
+
return v;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
Number_Obj v = SASS_MEMORY_COPY(&lhs);
|
|
157
|
+
|
|
158
|
+
if (lhs.is_unitless() && (op == Sass_OP::ADD || op == Sass_OP::SUB || op == Sass_OP::MOD)) {
|
|
159
|
+
v->numerators = rhs.numerators;
|
|
160
|
+
v->denominators = rhs.denominators;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (op == Sass_OP::MUL) {
|
|
164
|
+
v->value(ops[op](lval, rval));
|
|
165
|
+
v->numerators.insert(v->numerators.end(),
|
|
166
|
+
rhs.numerators.begin(), rhs.numerators.end()
|
|
167
|
+
);
|
|
168
|
+
v->denominators.insert(v->denominators.end(),
|
|
169
|
+
rhs.denominators.begin(), rhs.denominators.end()
|
|
170
|
+
);
|
|
171
|
+
v->reduce();
|
|
172
|
+
}
|
|
173
|
+
else if (op == Sass_OP::DIV) {
|
|
174
|
+
v->value(ops[op](lval, rval));
|
|
175
|
+
v->numerators.insert(v->numerators.end(),
|
|
176
|
+
rhs.denominators.begin(), rhs.denominators.end()
|
|
177
|
+
);
|
|
178
|
+
v->denominators.insert(v->denominators.end(),
|
|
179
|
+
rhs.numerators.begin(), rhs.numerators.end()
|
|
180
|
+
);
|
|
181
|
+
v->reduce();
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
Number ln(lhs), rn(rhs);
|
|
185
|
+
ln.reduce(); rn.reduce();
|
|
186
|
+
double f(rn.convert_factor(ln));
|
|
187
|
+
v->value(ops[op](lval, rn.value() * f));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
v->pstate(pstate);
|
|
191
|
+
return v.detach();
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/* static function, throws OperationError, has no traces but optional pstate for returned value */
|
|
195
|
+
Value_Ptr op_number_color(enum Sass_OP op, const Number& lhs, const Color& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
|
|
196
|
+
{
|
|
197
|
+
double lval = lhs.value();
|
|
198
|
+
switch (op) {
|
|
199
|
+
case Sass_OP::ADD:
|
|
200
|
+
case Sass_OP::MUL: {
|
|
201
|
+
return SASS_MEMORY_NEW(Color,
|
|
202
|
+
pstate,
|
|
203
|
+
ops[op](lval, rhs.r()),
|
|
204
|
+
ops[op](lval, rhs.g()),
|
|
205
|
+
ops[op](lval, rhs.b()),
|
|
206
|
+
rhs.a());
|
|
207
|
+
}
|
|
208
|
+
case Sass_OP::SUB:
|
|
209
|
+
case Sass_OP::DIV: {
|
|
210
|
+
std::string color(rhs.to_string(opt));
|
|
211
|
+
return SASS_MEMORY_NEW(String_Quoted,
|
|
212
|
+
pstate,
|
|
213
|
+
lhs.to_string(opt)
|
|
214
|
+
+ sass_op_separator(op)
|
|
215
|
+
+ color);
|
|
216
|
+
}
|
|
217
|
+
default: break;
|
|
218
|
+
}
|
|
219
|
+
throw Exception::UndefinedOperation(&lhs, &rhs, op);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/* static function, throws OperationError, has no traces but optional pstate for returned value */
|
|
223
|
+
Value_Ptr op_color_number(enum Sass_OP op, const Color& lhs, const Number& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
|
|
224
|
+
{
|
|
225
|
+
double rval = rhs.value();
|
|
226
|
+
if (op == Sass_OP::DIV && rval == 0) {
|
|
227
|
+
// comparison of Fixnum with Float failed?
|
|
228
|
+
throw Exception::ZeroDivisionError(lhs, rhs);
|
|
229
|
+
}
|
|
230
|
+
return SASS_MEMORY_NEW(Color,
|
|
231
|
+
pstate,
|
|
232
|
+
ops[op](lhs.r(), rval),
|
|
233
|
+
ops[op](lhs.g(), rval),
|
|
234
|
+
ops[op](lhs.b(), rval),
|
|
235
|
+
lhs.a());
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#ifndef SASS_OPERATORS_H
|
|
2
|
+
#define SASS_OPERATORS_H
|
|
3
|
+
|
|
4
|
+
#include "values.hpp"
|
|
5
|
+
#include "sass/values.h"
|
|
6
|
+
|
|
7
|
+
namespace Sass {
|
|
8
|
+
|
|
9
|
+
namespace Operators {
|
|
10
|
+
|
|
11
|
+
// equality operator using AST Node operator==
|
|
12
|
+
bool eq(Expression_Obj, Expression_Obj);
|
|
13
|
+
bool neq(Expression_Obj, Expression_Obj);
|
|
14
|
+
// specific operators based on cmp and eq
|
|
15
|
+
bool lt(Expression_Obj, Expression_Obj);
|
|
16
|
+
bool gt(Expression_Obj, Expression_Obj);
|
|
17
|
+
bool lte(Expression_Obj, Expression_Obj);
|
|
18
|
+
bool gte(Expression_Obj, Expression_Obj);
|
|
19
|
+
// arithmetic for all the combinations that matter
|
|
20
|
+
Value_Ptr op_strings(Sass::Operand, Value&, Value&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
|
|
21
|
+
Value_Ptr op_colors(enum Sass_OP, const Color&, const Color&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
|
|
22
|
+
Value_Ptr op_numbers(enum Sass_OP, const Number&, const Number&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
|
|
23
|
+
Value_Ptr op_number_color(enum Sass_OP, const Number&, const Color&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
|
|
24
|
+
Value_Ptr op_color_number(enum Sass_OP, const Color&, const Number&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
|
|
25
|
+
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
#endif
|
data/ext/libsass/src/output.cpp
CHANGED
|
@@ -19,13 +19,14 @@ namespace Sass {
|
|
|
19
19
|
|
|
20
20
|
void Output::operator()(Number_Ptr n)
|
|
21
21
|
{
|
|
22
|
-
// use values to_string facility
|
|
23
|
-
std::string res = n->to_string(opt);
|
|
24
22
|
// check for a valid unit here
|
|
25
23
|
// includes result for reporting
|
|
26
24
|
if (!n->is_valid_css_unit()) {
|
|
27
|
-
|
|
25
|
+
// should be handle in check_expression
|
|
26
|
+
throw Exception::InvalidValue({}, *n);
|
|
28
27
|
}
|
|
28
|
+
// use values to_string facility
|
|
29
|
+
std::string res = n->to_string(opt);
|
|
29
30
|
// output the final token
|
|
30
31
|
append_token(res, n);
|
|
31
32
|
}
|
|
@@ -37,8 +38,8 @@ namespace Sass {
|
|
|
37
38
|
|
|
38
39
|
void Output::operator()(Map_Ptr m)
|
|
39
40
|
{
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
// should be handle in check_expression
|
|
42
|
+
throw Exception::InvalidValue({}, *m);
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
OutputBuffer Output::get_buffer(void)
|
|
@@ -116,8 +117,8 @@ namespace Sass {
|
|
|
116
117
|
if (!Util::isPrintable(r, output_style())) {
|
|
117
118
|
for (size_t i = 0, L = b->length(); i < L; ++i) {
|
|
118
119
|
const Statement_Obj& stm = b->at(i);
|
|
119
|
-
if (
|
|
120
|
-
if (!
|
|
120
|
+
if (Cast<Has_Block>(stm)) {
|
|
121
|
+
if (!Cast<Declaration>(stm)) {
|
|
121
122
|
stm->perform(this);
|
|
122
123
|
}
|
|
123
124
|
}
|
|
@@ -134,28 +135,29 @@ namespace Sass {
|
|
|
134
135
|
append_string(ss.str());
|
|
135
136
|
append_optional_linefeed();
|
|
136
137
|
}
|
|
138
|
+
scheduled_crutch = s;
|
|
137
139
|
if (s) s->perform(this);
|
|
138
|
-
append_scope_opener(
|
|
140
|
+
append_scope_opener(b);
|
|
139
141
|
for (size_t i = 0, L = b->length(); i < L; ++i) {
|
|
140
142
|
Statement_Obj stm = b->at(i);
|
|
141
143
|
bool bPrintExpression = true;
|
|
142
144
|
// Check print conditions
|
|
143
|
-
if (Declaration_Ptr dec =
|
|
144
|
-
if (String_Constant_Ptr valConst =
|
|
145
|
+
if (Declaration_Ptr dec = Cast<Declaration>(stm)) {
|
|
146
|
+
if (String_Constant_Ptr valConst = Cast<String_Constant>(dec->value())) {
|
|
145
147
|
std::string val(valConst->value());
|
|
146
|
-
if (String_Quoted_Ptr qstr =
|
|
148
|
+
if (String_Quoted_Ptr qstr = Cast<String_Quoted>(valConst)) {
|
|
147
149
|
if (!qstr->quote_mark() && val.empty()) {
|
|
148
150
|
bPrintExpression = false;
|
|
149
151
|
}
|
|
150
152
|
}
|
|
151
153
|
}
|
|
152
|
-
else if (List_Ptr list =
|
|
154
|
+
else if (List_Ptr list = Cast<List>(dec->value())) {
|
|
153
155
|
bool all_invisible = true;
|
|
154
156
|
for (size_t list_i = 0, list_L = list->length(); list_i < list_L; ++list_i) {
|
|
155
|
-
Expression_Ptr item =
|
|
157
|
+
Expression_Ptr item = list->at(list_i);
|
|
156
158
|
if (!item->is_invisible()) all_invisible = false;
|
|
157
159
|
}
|
|
158
|
-
if (all_invisible) bPrintExpression = false;
|
|
160
|
+
if (all_invisible && !list->is_bracketed()) bPrintExpression = false;
|
|
159
161
|
}
|
|
160
162
|
}
|
|
161
163
|
// Print if OK
|
|
@@ -164,7 +166,7 @@ namespace Sass {
|
|
|
164
166
|
}
|
|
165
167
|
}
|
|
166
168
|
if (output_style() == NESTED) indentation -= r->tabs();
|
|
167
|
-
append_scope_closer(
|
|
169
|
+
append_scope_closer(b);
|
|
168
170
|
|
|
169
171
|
}
|
|
170
172
|
void Output::operator()(Keyframe_Rule_Ptr r)
|
|
@@ -172,7 +174,7 @@ namespace Sass {
|
|
|
172
174
|
Block_Obj b = r->block();
|
|
173
175
|
Selector_Obj v = r->name();
|
|
174
176
|
|
|
175
|
-
if (
|
|
177
|
+
if (!v.isNull()) {
|
|
176
178
|
v->perform(this);
|
|
177
179
|
}
|
|
178
180
|
|
|
@@ -201,7 +203,7 @@ namespace Sass {
|
|
|
201
203
|
if (!Util::isPrintable(f, output_style())) {
|
|
202
204
|
for (size_t i = 0, L = b->length(); i < L; ++i) {
|
|
203
205
|
Statement_Obj stm = b->at(i);
|
|
204
|
-
if (
|
|
206
|
+
if (Cast<Has_Block>(stm)) {
|
|
205
207
|
stm->perform(this);
|
|
206
208
|
}
|
|
207
209
|
}
|
|
@@ -237,7 +239,7 @@ namespace Sass {
|
|
|
237
239
|
if (!Util::isPrintable(m, output_style())) {
|
|
238
240
|
for (size_t i = 0, L = b->length(); i < L; ++i) {
|
|
239
241
|
Statement_Obj stm = b->at(i);
|
|
240
|
-
if (
|
|
242
|
+
if (Cast<Has_Block>(stm)) {
|
|
241
243
|
stm->perform(this);
|
|
242
244
|
}
|
|
243
245
|
}
|
|
@@ -282,7 +284,7 @@ namespace Sass {
|
|
|
282
284
|
if (v) {
|
|
283
285
|
append_mandatory_space();
|
|
284
286
|
// ruby sass bug? should use options?
|
|
285
|
-
append_token(v->to_string(/* opt */),
|
|
287
|
+
append_token(v->to_string(/* opt */), v);
|
|
286
288
|
}
|
|
287
289
|
if (!b) {
|
|
288
290
|
append_delimiter();
|
|
@@ -324,7 +326,7 @@ namespace Sass {
|
|
|
324
326
|
if (s->can_compress_whitespace() && output_style() == COMPRESSED) {
|
|
325
327
|
value.erase(std::remove_if(value.begin(), value.end(), ::isspace), value.end());
|
|
326
328
|
}
|
|
327
|
-
if (!in_comment) {
|
|
329
|
+
if (!in_comment && !in_custom_property) {
|
|
328
330
|
append_token(string_to_output(value), s);
|
|
329
331
|
} else {
|
|
330
332
|
append_token(value, s);
|