sassc 0.0.9 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +1 -1
- data/ext/libsass/.gitignore +13 -6
- data/ext/libsass/Makefile +42 -26
- data/ext/libsass/Makefile.am +43 -30
- data/ext/libsass/Readme.md +4 -2
- data/ext/libsass/appveyor.yml +10 -14
- data/ext/libsass/ast.cpp +54 -44
- data/ext/libsass/ast.hpp +404 -236
- data/ext/libsass/ast_def_macros.hpp +5 -0
- data/ext/libsass/ast_factory.hpp +6 -3
- data/ext/libsass/ast_fwd_decl.hpp +12 -0
- data/ext/libsass/b64/encode.h +2 -2
- data/ext/libsass/backtrace.hpp +13 -17
- data/ext/libsass/base64vlq.hpp +4 -1
- data/ext/libsass/bind.cpp +12 -15
- data/ext/libsass/bind.hpp +6 -6
- data/ext/libsass/color_names.hpp +4 -1
- data/ext/libsass/configure.ac +7 -21
- data/ext/libsass/constants.cpp +6 -4
- data/ext/libsass/constants.hpp +10 -4
- data/ext/libsass/context.cpp +89 -58
- data/ext/libsass/context.hpp +28 -35
- data/ext/libsass/contextualize.cpp +20 -10
- data/ext/libsass/contextualize.hpp +8 -23
- data/ext/libsass/contrib/libsass.spec +66 -0
- data/ext/libsass/cssize.cpp +547 -0
- data/ext/libsass/cssize.hpp +82 -0
- data/ext/libsass/debug.hpp +3 -3
- data/ext/libsass/debugger.hpp +358 -0
- data/ext/libsass/emitter.cpp +255 -0
- data/ext/libsass/emitter.hpp +83 -0
- data/ext/libsass/environment.hpp +7 -3
- data/ext/libsass/error_handling.cpp +11 -14
- data/ext/libsass/error_handling.hpp +9 -7
- data/ext/libsass/eval.cpp +253 -161
- data/ext/libsass/eval.hpp +13 -13
- data/ext/libsass/expand.cpp +135 -64
- data/ext/libsass/expand.hpp +11 -13
- data/ext/libsass/extend.cpp +66 -20
- data/ext/libsass/extend.hpp +6 -11
- data/ext/libsass/file.cpp +31 -26
- data/ext/libsass/file.hpp +6 -1
- data/ext/libsass/functions.cpp +270 -287
- data/ext/libsass/functions.hpp +8 -11
- data/ext/libsass/inspect.cpp +385 -255
- data/ext/libsass/inspect.hpp +15 -26
- data/ext/libsass/kwd_arg_macros.hpp +5 -0
- data/ext/libsass/mapping.hpp +4 -3
- data/ext/libsass/memory_manager.hpp +5 -2
- data/ext/libsass/node.cpp +50 -50
- data/ext/libsass/node.hpp +26 -27
- data/ext/libsass/operation.hpp +15 -4
- data/ext/libsass/output.cpp +401 -0
- data/ext/libsass/output.hpp +56 -0
- data/ext/libsass/parser.cpp +573 -399
- data/ext/libsass/parser.hpp +122 -88
- data/ext/libsass/paths.hpp +7 -2
- data/ext/libsass/plugins.cpp +155 -0
- data/ext/libsass/plugins.hpp +56 -0
- data/ext/libsass/position.cpp +128 -0
- data/ext/libsass/position.hpp +108 -11
- data/ext/libsass/prelexer.cpp +184 -110
- data/ext/libsass/prelexer.hpp +131 -24
- data/ext/libsass/remove_placeholders.cpp +1 -1
- data/ext/libsass/remove_placeholders.hpp +6 -6
- data/ext/libsass/sass.cpp +3 -3
- data/ext/libsass/sass.h +12 -4
- data/ext/libsass/sass2scss.cpp +3 -2
- data/ext/libsass/sass2scss.h +5 -0
- data/ext/libsass/sass_context.cpp +136 -37
- data/ext/libsass/sass_context.h +19 -10
- data/ext/libsass/sass_functions.cpp +29 -2
- data/ext/libsass/sass_functions.h +8 -2
- data/ext/libsass/sass_interface.cpp +32 -23
- data/ext/libsass/sass_interface.h +9 -4
- data/ext/libsass/sass_util.cpp +19 -23
- data/ext/libsass/sass_util.hpp +28 -27
- data/ext/libsass/sass_values.cpp +6 -4
- data/ext/libsass/sass_values.h +3 -3
- data/ext/libsass/script/ci-build-libsass +13 -1
- data/ext/libsass/script/ci-report-coverage +2 -1
- data/ext/libsass/source_map.cpp +79 -28
- data/ext/libsass/source_map.hpp +35 -16
- data/ext/libsass/subset_map.hpp +6 -4
- data/ext/libsass/to_c.hpp +4 -4
- data/ext/libsass/to_string.cpp +13 -8
- data/ext/libsass/to_string.hpp +6 -4
- data/ext/libsass/units.cpp +2 -1
- data/ext/libsass/units.hpp +6 -1
- data/ext/libsass/utf8_string.cpp +0 -5
- data/ext/libsass/utf8_string.hpp +3 -2
- data/ext/libsass/util.cpp +461 -49
- data/ext/libsass/util.hpp +34 -13
- data/ext/libsass/version.sh +10 -0
- data/ext/libsass/win/libsass.filters +20 -11
- data/ext/libsass/win/libsass.vcxproj +11 -8
- data/lib/sassc/importer.rb +1 -8
- data/lib/sassc/native.rb +7 -0
- data/lib/sassc/native/native_context_api.rb +5 -5
- data/lib/sassc/version.rb +1 -1
- data/test/native_test.rb +1 -1
- metadata +14 -10
- data/ext/libsass/copy_c_str.cpp +0 -13
- data/ext/libsass/copy_c_str.hpp +0 -5
- data/ext/libsass/output_compressed.cpp +0 -401
- data/ext/libsass/output_compressed.hpp +0 -95
- data/ext/libsass/output_nested.cpp +0 -364
- data/ext/libsass/output_nested.hpp +0 -108
- data/ext/libsass/test-driver +0 -127
- data/ext/libsass/token.hpp +0 -32
data/ext/libsass/expand.hpp
CHANGED
|
@@ -1,27 +1,19 @@
|
|
|
1
|
-
#
|
|
1
|
+
#ifndef SASS_EXPAND_H
|
|
2
|
+
#define SASS_EXPAND_H
|
|
2
3
|
|
|
3
|
-
#include <vector>
|
|
4
4
|
#include <map>
|
|
5
|
+
#include <vector>
|
|
5
6
|
#include <iostream>
|
|
6
7
|
|
|
7
|
-
#ifndef SASS_AST
|
|
8
8
|
#include "ast.hpp"
|
|
9
|
-
#
|
|
10
|
-
|
|
11
|
-
#ifndef SASS_OPERATION
|
|
9
|
+
#include "eval.hpp"
|
|
12
10
|
#include "operation.hpp"
|
|
13
|
-
#endif
|
|
14
|
-
|
|
15
|
-
#ifndef SASS_ENVIRONMENT
|
|
16
11
|
#include "environment.hpp"
|
|
17
|
-
#
|
|
12
|
+
#include "contextualize.hpp"
|
|
18
13
|
|
|
19
14
|
namespace Sass {
|
|
20
15
|
using namespace std;
|
|
21
16
|
|
|
22
|
-
struct Context;
|
|
23
|
-
class Eval;
|
|
24
|
-
class Contextualize;
|
|
25
17
|
typedef Environment<AST_Node*> Env;
|
|
26
18
|
struct Backtrace;
|
|
27
19
|
|
|
@@ -34,6 +26,9 @@ namespace Sass {
|
|
|
34
26
|
vector<Block*> block_stack;
|
|
35
27
|
vector<String*> property_stack;
|
|
36
28
|
vector<Selector*> selector_stack;
|
|
29
|
+
vector<Selector*> at_root_selector_stack;
|
|
30
|
+
bool in_at_root;
|
|
31
|
+
bool in_keyframes;
|
|
37
32
|
Backtrace* backtrace;
|
|
38
33
|
|
|
39
34
|
Statement* fallback_impl(AST_Node* n);
|
|
@@ -49,6 +44,7 @@ namespace Sass {
|
|
|
49
44
|
Statement* operator()(Propset*);
|
|
50
45
|
Statement* operator()(Media_Block*);
|
|
51
46
|
Statement* operator()(Feature_Block*);
|
|
47
|
+
Statement* operator()(At_Root_Block*);
|
|
52
48
|
Statement* operator()(At_Rule*);
|
|
53
49
|
Statement* operator()(Declaration*);
|
|
54
50
|
Statement* operator()(Assignment*);
|
|
@@ -75,3 +71,5 @@ namespace Sass {
|
|
|
75
71
|
};
|
|
76
72
|
|
|
77
73
|
}
|
|
74
|
+
|
|
75
|
+
#endif
|
data/ext/libsass/extend.cpp
CHANGED
|
@@ -5,9 +5,7 @@
|
|
|
5
5
|
#include "backtrace.hpp"
|
|
6
6
|
#include "paths.hpp"
|
|
7
7
|
#include "parser.hpp"
|
|
8
|
-
#ifndef SASS_AST
|
|
9
8
|
#include "node.hpp"
|
|
10
|
-
#endif
|
|
11
9
|
#include "sass_util.hpp"
|
|
12
10
|
#include "debug.hpp"
|
|
13
11
|
#include <iostream>
|
|
@@ -237,14 +235,15 @@ namespace Sass {
|
|
|
237
235
|
return os;
|
|
238
236
|
}
|
|
239
237
|
#endif
|
|
238
|
+
|
|
240
239
|
static bool parentSuperselector(Complex_Selector* pOne, Complex_Selector* pTwo, Context& ctx) {
|
|
241
240
|
// TODO: figure out a better way to create a Complex_Selector from scratch
|
|
242
241
|
// TODO: There's got to be a better way. This got ugly quick...
|
|
243
|
-
Position noPosition;
|
|
244
|
-
Type_Selector fakeParent("",
|
|
245
|
-
Compound_Selector fakeHead("",
|
|
242
|
+
Position noPosition(-1, -1, -1);
|
|
243
|
+
Type_Selector fakeParent(ParserState("[FAKE]"), "temp");
|
|
244
|
+
Compound_Selector fakeHead(ParserState("[FAKE]"), 1 /*size*/);
|
|
246
245
|
fakeHead.elements().push_back(&fakeParent);
|
|
247
|
-
Complex_Selector fakeParentContainer("",
|
|
246
|
+
Complex_Selector fakeParentContainer(ParserState("[FAKE]"), Complex_Selector::ANCESTOR_OF, &fakeHead /*head*/, NULL /*tail*/);
|
|
248
247
|
|
|
249
248
|
pOne->set_innermost(&fakeParentContainer, Complex_Selector::ANCESTOR_OF);
|
|
250
249
|
pTwo->set_innermost(&fakeParentContainer, Complex_Selector::ANCESTOR_OF);
|
|
@@ -602,11 +601,11 @@ namespace Sass {
|
|
|
602
601
|
static bool parentSuperselector(const Node& one, const Node& two, Context& ctx) {
|
|
603
602
|
// TODO: figure out a better way to create a Complex_Selector from scratch
|
|
604
603
|
// TODO: There's got to be a better way. This got ugly quick...
|
|
605
|
-
Position noPosition;
|
|
606
|
-
Type_Selector fakeParent("",
|
|
607
|
-
Compound_Selector fakeHead("",
|
|
604
|
+
Position noPosition(-1, -1, -1);
|
|
605
|
+
Type_Selector fakeParent(ParserState("[FAKE]"), "temp");
|
|
606
|
+
Compound_Selector fakeHead(ParserState("[FAKE]"), 1 /*size*/);
|
|
608
607
|
fakeHead.elements().push_back(&fakeParent);
|
|
609
|
-
Complex_Selector fakeParentContainer("",
|
|
608
|
+
Complex_Selector fakeParentContainer(ParserState("[FAKE]"), Complex_Selector::ANCESTOR_OF, &fakeHead /*head*/, NULL /*tail*/);
|
|
610
609
|
|
|
611
610
|
Complex_Selector* pOneWithFakeParent = nodeToComplexSelector(one, ctx);
|
|
612
611
|
pOneWithFakeParent->set_innermost(&fakeParentContainer, Complex_Selector::ANCESTOR_OF);
|
|
@@ -1521,7 +1520,7 @@ namespace Sass {
|
|
|
1521
1520
|
// DEBUG_EXEC(EXTEND_COMPOUND, printComplexSelector(&seq, "SEQ: "))
|
|
1522
1521
|
|
|
1523
1522
|
|
|
1524
|
-
Compound_Selector* pSels = new (ctx.mem) Compound_Selector(pSelector->
|
|
1523
|
+
Compound_Selector* pSels = new (ctx.mem) Compound_Selector(pSelector->pstate());
|
|
1525
1524
|
for (vector<ExtensionPair>::iterator groupIter = group.begin(), groupIterEnd = group.end(); groupIter != groupIterEnd; groupIter++) {
|
|
1526
1525
|
ExtensionPair& pair = *groupIter;
|
|
1527
1526
|
Compound_Selector* pCompound = pair.second;
|
|
@@ -1553,7 +1552,7 @@ namespace Sass {
|
|
|
1553
1552
|
Compound_Selector* pUnifiedSelector = NULL;
|
|
1554
1553
|
|
|
1555
1554
|
if (!pInnermostCompoundSelector) {
|
|
1556
|
-
pInnermostCompoundSelector = new (ctx.mem) Compound_Selector(pSelector->
|
|
1555
|
+
pInnermostCompoundSelector = new (ctx.mem) Compound_Selector(pSelector->pstate());
|
|
1557
1556
|
}
|
|
1558
1557
|
|
|
1559
1558
|
pUnifiedSelector = pInnermostCompoundSelector->unify_with(pSelectorWithoutExtendSelectors, ctx);
|
|
@@ -1579,7 +1578,7 @@ namespace Sass {
|
|
|
1579
1578
|
// complex is that Complex_Selector contains a combinator, but in ruby combinators have already been filtered
|
|
1580
1579
|
// out and aren't operated on.
|
|
1581
1580
|
Complex_Selector* pNewSelector = pExtComplexSelector->cloneFully(ctx);
|
|
1582
|
-
Complex_Selector* pNewInnerMost = new (ctx.mem) Complex_Selector(pSelector->
|
|
1581
|
+
Complex_Selector* pNewInnerMost = new (ctx.mem) Complex_Selector(pSelector->pstate(), Complex_Selector::ANCESTOR_OF, pUnifiedSelector, NULL);
|
|
1583
1582
|
Complex_Selector::Combinator combinator = pNewSelector->clear_innermost();
|
|
1584
1583
|
pNewSelector->set_innermost(pNewInnerMost, combinator);
|
|
1585
1584
|
|
|
@@ -1596,6 +1595,7 @@ namespace Sass {
|
|
|
1596
1595
|
#endif
|
|
1597
1596
|
|
|
1598
1597
|
|
|
1598
|
+
if (pSelector && pSelector->has_line_feed()) pNewSelector->has_line_feed(true);
|
|
1599
1599
|
|
|
1600
1600
|
// Set the sources on our new Complex_Selector to the sources of this simple sequence plus the thing we're extending.
|
|
1601
1601
|
DEBUG_PRINTLN(EXTEND_COMPOUND, "SOURCES SETTING ON NEW SEQ: " << complexSelectorToNode(pNewSelector, ctx))
|
|
@@ -1675,13 +1675,58 @@ namespace Sass {
|
|
|
1675
1675
|
|
|
1676
1676
|
if (pHead) {
|
|
1677
1677
|
SubsetMapEntries entries = subsetMap.get_v(pHead->to_str_vec());
|
|
1678
|
+
for (ExtensionPair ext : entries) {
|
|
1679
|
+
// check if both selectors have the same media block parent
|
|
1680
|
+
if (ext.first->media_block() == pComplexSelector->media_block()) continue;
|
|
1681
|
+
To_String to_string(&ctx);
|
|
1682
|
+
if (ext.second->media_block() && ext.second->media_block()->media_queries() &&
|
|
1683
|
+
pComplexSelector->media_block() && pComplexSelector->media_block()->media_queries())
|
|
1684
|
+
{
|
|
1685
|
+
string query_left(ext.second->media_block()->media_queries()->perform(&to_string));
|
|
1686
|
+
string query_right(pComplexSelector->media_block()->media_queries()->perform(&to_string));
|
|
1687
|
+
if (query_left == query_right) continue;
|
|
1688
|
+
}
|
|
1678
1689
|
|
|
1679
|
-
|
|
1690
|
+
// fail if one goes across media block boundaries
|
|
1691
|
+
stringstream err;
|
|
1692
|
+
string cwd(Sass::File::get_cwd());
|
|
1693
|
+
ParserState pstate(ext.second->pstate());
|
|
1694
|
+
string rel_path(Sass::File::resolve_relative_path(pstate.path, cwd, cwd));
|
|
1695
|
+
err << "You may not @extend an outer selector from within @media.\n";
|
|
1696
|
+
err << "You may only @extend selectors within the same directive.\n";
|
|
1697
|
+
err << "From \"@extend " << ext.second->perform(&to_string) << "\"";
|
|
1698
|
+
err << " on line " << pstate.line+1 << " of " << rel_path << "\n";
|
|
1699
|
+
error(err.str(), pComplexSelector->pstate());
|
|
1700
|
+
}
|
|
1701
|
+
if (entries.size() > 0) hasExtension = true;
|
|
1680
1702
|
}
|
|
1681
1703
|
|
|
1682
1704
|
pIter = pIter->tail();
|
|
1683
1705
|
}
|
|
1684
1706
|
|
|
1707
|
+
if (!hasExtension) {
|
|
1708
|
+
/* ToDo: don't break stuff
|
|
1709
|
+
stringstream err;
|
|
1710
|
+
To_String to_string(&ctx);
|
|
1711
|
+
string cwd(Sass::File::get_cwd());
|
|
1712
|
+
string sel1(pComplexSelector->perform(&to_string));
|
|
1713
|
+
Compound_Selector* pExtendSelector = 0;
|
|
1714
|
+
for (auto i : subsetMap.values()) {
|
|
1715
|
+
if (i.first == pComplexSelector) {
|
|
1716
|
+
pExtendSelector = i.second;
|
|
1717
|
+
break;
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
if (!pExtendSelector || !pExtendSelector->is_optional()) {
|
|
1721
|
+
string sel2(pExtendSelector ? pExtendSelector->perform(&to_string) : "[unknown]");
|
|
1722
|
+
err << "\"" << sel1 << "\" failed to @extend \"" << sel2 << "\"\n";
|
|
1723
|
+
err << "The selector \"" << sel2 << "\" was not found.\n";
|
|
1724
|
+
err << "Use \"@extend " << sel2 << " !optional\" if the extend should be able to fail.";
|
|
1725
|
+
error(err.str(), pExtendSelector ? pExtendSelector->pstate() : pComplexSelector->pstate());
|
|
1726
|
+
}
|
|
1727
|
+
*/
|
|
1728
|
+
}
|
|
1729
|
+
|
|
1685
1730
|
return hasExtension;
|
|
1686
1731
|
}
|
|
1687
1732
|
|
|
@@ -1703,8 +1748,9 @@ namespace Sass {
|
|
|
1703
1748
|
ExtensionSubsetMap& subsetMap,
|
|
1704
1749
|
set<Compound_Selector> seen) {
|
|
1705
1750
|
|
|
1706
|
-
|
|
1751
|
+
pComplexSelector->tail()->has_line_feed(pComplexSelector->has_line_feed());
|
|
1707
1752
|
|
|
1753
|
+
Node complexSelector = complexSelectorToNode(pComplexSelector, ctx);
|
|
1708
1754
|
DEBUG_PRINTLN(EXTEND_COMPLEX, "EXTEND COMPLEX: " << complexSelector)
|
|
1709
1755
|
|
|
1710
1756
|
Node extendedNotExpanded = Node::createCollection();
|
|
@@ -1808,9 +1854,9 @@ namespace Sass {
|
|
|
1808
1854
|
*/
|
|
1809
1855
|
static Selector_List* extendSelectorList(Selector_List* pSelectorList, Context& ctx, ExtensionSubsetMap& subsetMap, bool& extendedSomething) {
|
|
1810
1856
|
|
|
1811
|
-
To_String to_string;
|
|
1857
|
+
To_String to_string(&ctx);
|
|
1812
1858
|
|
|
1813
|
-
Selector_List* pNewSelectors = new (ctx.mem) Selector_List(pSelectorList->
|
|
1859
|
+
Selector_List* pNewSelectors = new (ctx.mem) Selector_List(pSelectorList->pstate(), pSelectorList->length());
|
|
1814
1860
|
|
|
1815
1861
|
extendedSomething = false;
|
|
1816
1862
|
|
|
@@ -1883,7 +1929,7 @@ namespace Sass {
|
|
|
1883
1929
|
// Extend a ruleset by extending the selectors and updating them on the ruleset. The block's rules don't need to change.
|
|
1884
1930
|
template <typename ObjectType>
|
|
1885
1931
|
static void extendObjectWithSelectorAndBlock(ObjectType* pObject, Context& ctx, ExtensionSubsetMap& subsetMap) {
|
|
1886
|
-
To_String to_string;
|
|
1932
|
+
To_String to_string(&ctx);
|
|
1887
1933
|
|
|
1888
1934
|
DEBUG_PRINTLN(EXTEND_OBJECT, "FOUND SELECTOR: " << static_cast<Selector_List*>(pObject->selector())->perform(&to_string))
|
|
1889
1935
|
|
|
@@ -1904,12 +1950,12 @@ namespace Sass {
|
|
|
1904
1950
|
// re-parse in order to restructure expanded placeholder nodes correctly.
|
|
1905
1951
|
//
|
|
1906
1952
|
// TODO: I don't know if this is needed, but it was in the original C++ implementation, so I kept it. Try running the tests without re-parsing.
|
|
1953
|
+
// this probably messes up source-maps
|
|
1907
1954
|
pObject->selector(
|
|
1908
1955
|
Parser::from_c_str(
|
|
1909
1956
|
(pNewSelectorList->perform(&to_string) + ";").c_str(),
|
|
1910
1957
|
ctx,
|
|
1911
|
-
pNewSelectorList->
|
|
1912
|
-
pNewSelectorList->position()
|
|
1958
|
+
pNewSelectorList->pstate()
|
|
1913
1959
|
).parse_selector_group()
|
|
1914
1960
|
);
|
|
1915
1961
|
} else {
|
data/ext/libsass/extend.hpp
CHANGED
|
@@ -1,26 +1,19 @@
|
|
|
1
|
-
#
|
|
1
|
+
#ifndef SASS_EXTEND_H
|
|
2
|
+
#define SASS_EXTEND_H
|
|
2
3
|
|
|
3
|
-
#include <vector>
|
|
4
4
|
#include <map>
|
|
5
5
|
#include <set>
|
|
6
|
+
#include <vector>
|
|
6
7
|
#include <iostream>
|
|
7
8
|
|
|
8
|
-
#ifndef SASS_AST
|
|
9
9
|
#include "ast.hpp"
|
|
10
|
-
#endif
|
|
11
|
-
|
|
12
|
-
#ifndef SASS_OPERATION
|
|
13
10
|
#include "operation.hpp"
|
|
14
|
-
#endif
|
|
15
|
-
|
|
16
|
-
#ifndef SASS_SUBSET_MAP
|
|
17
11
|
#include "subset_map.hpp"
|
|
18
|
-
#endif
|
|
19
12
|
|
|
20
13
|
namespace Sass {
|
|
21
14
|
using namespace std;
|
|
22
15
|
|
|
23
|
-
|
|
16
|
+
class Context;
|
|
24
17
|
|
|
25
18
|
typedef Subset_Map<string, pair<Complex_Selector*, Compound_Selector*> > ExtensionSubsetMap;
|
|
26
19
|
|
|
@@ -48,3 +41,5 @@ namespace Sass {
|
|
|
48
41
|
};
|
|
49
42
|
|
|
50
43
|
}
|
|
44
|
+
|
|
45
|
+
#endif
|
data/ext/libsass/file.cpp
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
#include <iostream>
|
|
10
10
|
#include <fstream>
|
|
11
11
|
#include <cctype>
|
|
12
|
+
#include <vector>
|
|
12
13
|
#include <algorithm>
|
|
13
14
|
#include <sys/stat.h>
|
|
14
15
|
#include "file.hpp"
|
|
@@ -202,34 +203,38 @@ namespace Sass {
|
|
|
202
203
|
// (4) given + extension
|
|
203
204
|
char* contents = 0;
|
|
204
205
|
real_path = path;
|
|
205
|
-
|
|
206
|
+
vector<string> exts(3);
|
|
207
|
+
exts[0] = ".scss";
|
|
208
|
+
exts[1] = ".sass";
|
|
209
|
+
exts[2] = ".css";
|
|
210
|
+
|
|
211
|
+
// if the file isn't found with the given filename (1)
|
|
206
212
|
if (!(contents = read_file(real_path))) {
|
|
207
213
|
string dir(dir_name(path));
|
|
208
214
|
string base(base_name(path));
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
if (
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
}
|
|
215
|
+
real_path = dir + base;
|
|
216
|
+
// (2) underscore + given
|
|
217
|
+
string test_path(dir + "_" + base);
|
|
218
|
+
if ((contents = read_file(test_path))) {
|
|
219
|
+
real_path = test_path;
|
|
220
|
+
}
|
|
221
|
+
// (3) underscore + given + extension
|
|
222
|
+
if (!contents) {
|
|
223
|
+
for(auto ext : exts) {
|
|
224
|
+
test_path = dir + "_" + base + ext;
|
|
225
|
+
if ((contents = read_file(test_path))) {
|
|
226
|
+
real_path = test_path;
|
|
227
|
+
break;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
// (4) given + extension
|
|
232
|
+
if (!contents) {
|
|
233
|
+
for(auto ext : exts) {
|
|
234
|
+
test_path = dir + base + ext;
|
|
235
|
+
if ((contents = read_file(test_path))) {
|
|
236
|
+
real_path = test_path;
|
|
237
|
+
break;
|
|
233
238
|
}
|
|
234
239
|
}
|
|
235
240
|
}
|
|
@@ -279,7 +284,7 @@ namespace Sass {
|
|
|
279
284
|
for(size_t i=0; i<extension.size();++i)
|
|
280
285
|
extension[i] = tolower(extension[i]);
|
|
281
286
|
if (extension == ".sass" && contents != 0) {
|
|
282
|
-
char * converted = sass2scss(contents, SASS2SCSS_PRETTIFY_1);
|
|
287
|
+
char * converted = sass2scss(contents, SASS2SCSS_PRETTIFY_1 | SASS2SCSS_KEEP_COMMENT);
|
|
283
288
|
delete[] contents; // free the indented contents
|
|
284
289
|
return converted; // should be freed by caller
|
|
285
290
|
} else {
|
data/ext/libsass/file.hpp
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
#ifndef SASS_FILE_H
|
|
2
|
+
#define SASS_FILE_H
|
|
3
|
+
|
|
1
4
|
#include <string>
|
|
2
5
|
|
|
3
6
|
namespace Sass {
|
|
4
7
|
using namespace std;
|
|
5
|
-
|
|
8
|
+
class Context;
|
|
6
9
|
namespace File {
|
|
7
10
|
string get_cwd();
|
|
8
11
|
string base_name(string);
|
|
@@ -16,3 +19,5 @@ namespace Sass {
|
|
|
16
19
|
char* read_file(string path);
|
|
17
20
|
}
|
|
18
21
|
}
|
|
22
|
+
|
|
23
|
+
#endif
|
data/ext/libsass/functions.cpp
CHANGED
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
#include "wincrypt.h"
|
|
28
28
|
#endif
|
|
29
29
|
|
|
30
|
-
#define ARG(argname, argtype) get_arg<argtype>(argname, env, sig,
|
|
31
|
-
#define ARGR(argname, argtype, lo, hi) get_arg_r(argname, env, sig,
|
|
32
|
-
#define ARGM(argname, argtype, ctx) get_arg_m(argname, env, sig,
|
|
30
|
+
#define ARG(argname, argtype) get_arg<argtype>(argname, env, sig, pstate, backtrace)
|
|
31
|
+
#define ARGR(argname, argtype, lo, hi) get_arg_r(argname, env, sig, pstate, lo, hi, backtrace)
|
|
32
|
+
#define ARGM(argname, argtype, ctx) get_arg_m(argname, env, sig, pstate, backtrace, ctx)
|
|
33
33
|
|
|
34
34
|
namespace Sass {
|
|
35
35
|
using std::stringstream;
|
|
@@ -37,12 +37,11 @@ namespace Sass {
|
|
|
37
37
|
|
|
38
38
|
Definition* make_native_function(Signature sig, Native_Function f, Context& ctx)
|
|
39
39
|
{
|
|
40
|
-
Parser sig_parser = Parser::from_c_str(sig, ctx, "[built-in function]");
|
|
40
|
+
Parser sig_parser = Parser::from_c_str(sig, ctx, ParserState("[built-in function]"));
|
|
41
41
|
sig_parser.lex<Prelexer::identifier>();
|
|
42
42
|
string name(Util::normalize_underscores(sig_parser.lexed));
|
|
43
43
|
Parameters* params = sig_parser.parse_parameters();
|
|
44
|
-
return new (ctx.mem) Definition("[built-in function]",
|
|
45
|
-
Position(),
|
|
44
|
+
return new (ctx.mem) Definition(ParserState("[built-in function]"),
|
|
46
45
|
sig,
|
|
47
46
|
name,
|
|
48
47
|
params,
|
|
@@ -52,7 +51,7 @@ namespace Sass {
|
|
|
52
51
|
|
|
53
52
|
Definition* make_c_function(Signature sig, Sass_C_Function f, void* cookie, Context& ctx)
|
|
54
53
|
{
|
|
55
|
-
Parser sig_parser = Parser::from_c_str(sig, ctx, "[c function]");
|
|
54
|
+
Parser sig_parser = Parser::from_c_str(sig, ctx, ParserState("[c function]"));
|
|
56
55
|
// allow to overload generic callback plus @warn, @error and @debug with custom functions
|
|
57
56
|
sig_parser.lex < alternatives < identifier, exactly <'*'>,
|
|
58
57
|
exactly < Constants::warn_kwd >,
|
|
@@ -61,8 +60,7 @@ namespace Sass {
|
|
|
61
60
|
> >();
|
|
62
61
|
string name(Util::normalize_underscores(sig_parser.lexed));
|
|
63
62
|
Parameters* params = sig_parser.parse_parameters();
|
|
64
|
-
return new (ctx.mem) Definition("[c function]",
|
|
65
|
-
Position(),
|
|
63
|
+
return new (ctx.mem) Definition(ParserState("[c function]"),
|
|
66
64
|
sig,
|
|
67
65
|
name,
|
|
68
66
|
params,
|
|
@@ -74,7 +72,7 @@ namespace Sass {
|
|
|
74
72
|
namespace Functions {
|
|
75
73
|
|
|
76
74
|
template <typename T>
|
|
77
|
-
T* get_arg(const string& argname, Env& env, Signature sig,
|
|
75
|
+
T* get_arg(const string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace)
|
|
78
76
|
{
|
|
79
77
|
// Minimal error handling -- the expectation is that built-ins will be written correctly!
|
|
80
78
|
T* val = dynamic_cast<T*>(env[argname]);
|
|
@@ -85,35 +83,35 @@ namespace Sass {
|
|
|
85
83
|
msg += sig;
|
|
86
84
|
msg += "` must be a ";
|
|
87
85
|
msg += T::type_name();
|
|
88
|
-
error(msg,
|
|
86
|
+
error(msg, pstate, backtrace);
|
|
89
87
|
}
|
|
90
88
|
return val;
|
|
91
89
|
}
|
|
92
90
|
|
|
93
|
-
Map* get_arg_m(const string& argname, Env& env, Signature sig,
|
|
91
|
+
Map* get_arg_m(const string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx)
|
|
94
92
|
{
|
|
95
93
|
// Minimal error handling -- the expectation is that built-ins will be written correctly!
|
|
96
94
|
Map* val = dynamic_cast<Map*>(env[argname]);
|
|
97
95
|
if (val) return val;
|
|
98
96
|
|
|
99
97
|
List* lval = dynamic_cast<List*>(env[argname]);
|
|
100
|
-
if (lval && lval->length() == 0) return new (ctx.mem) Map(
|
|
98
|
+
if (lval && lval->length() == 0) return new (ctx.mem) Map(pstate, 0);
|
|
101
99
|
|
|
102
100
|
// fallback on get_arg for error handling
|
|
103
|
-
val = get_arg<Map>(argname, env, sig,
|
|
101
|
+
val = get_arg<Map>(argname, env, sig, pstate, backtrace);
|
|
104
102
|
return val;
|
|
105
103
|
}
|
|
106
104
|
|
|
107
|
-
Number* get_arg_r(const string& argname, Env& env, Signature sig,
|
|
105
|
+
Number* get_arg_r(const string& argname, Env& env, Signature sig, ParserState pstate, double lo, double hi, Backtrace* backtrace)
|
|
108
106
|
{
|
|
109
107
|
// Minimal error handling -- the expectation is that built-ins will be written correctly!
|
|
110
|
-
Number* val = get_arg<Number>(argname, env, sig,
|
|
108
|
+
Number* val = get_arg<Number>(argname, env, sig, pstate, backtrace);
|
|
111
109
|
double v = val->value();
|
|
112
110
|
if (!(lo <= v && v <= hi)) {
|
|
113
111
|
stringstream msg;
|
|
114
112
|
msg << "argument `" << argname << "` of `" << sig << "` must be between ";
|
|
115
113
|
msg << lo << " and " << hi;
|
|
116
|
-
error(msg.str(),
|
|
114
|
+
error(msg.str(), pstate, backtrace);
|
|
117
115
|
}
|
|
118
116
|
return val;
|
|
119
117
|
}
|
|
@@ -144,7 +142,7 @@ namespace Sass {
|
|
|
144
142
|
// random_device degrades sharply once the entropy pool
|
|
145
143
|
// is exhausted. For practical use, random_device is
|
|
146
144
|
// generally only used to seed a PRNG such as mt19937.
|
|
147
|
-
static mt19937 rand(GetSeed());
|
|
145
|
+
static mt19937 rand(static_cast<unsigned int>(GetSeed()));
|
|
148
146
|
|
|
149
147
|
// features
|
|
150
148
|
static set<string> features;
|
|
@@ -153,24 +151,30 @@ namespace Sass {
|
|
|
153
151
|
// RGB FUNCTIONS
|
|
154
152
|
////////////////
|
|
155
153
|
|
|
154
|
+
inline double color_num(Number* n) {
|
|
155
|
+
if (n->unit() == "%") {
|
|
156
|
+
return std::min(std::max(n->value(), 0.0), 1.0) * 255;
|
|
157
|
+
} else {
|
|
158
|
+
return std::min(std::max(n->value(), 0.0), 255.0);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
156
162
|
Signature rgb_sig = "rgb($red, $green, $blue)";
|
|
157
163
|
BUILT_IN(rgb)
|
|
158
164
|
{
|
|
159
|
-
return new (ctx.mem) Color(
|
|
160
|
-
|
|
161
|
-
ARGR("$
|
|
162
|
-
ARGR("$
|
|
163
|
-
ARGR("$blue", Number, 0, 255)->value());
|
|
165
|
+
return new (ctx.mem) Color(pstate,
|
|
166
|
+
color_num(ARGR("$red", Number, 0, 255)),
|
|
167
|
+
color_num(ARGR("$green", Number, 0, 255)),
|
|
168
|
+
color_num(ARGR("$blue", Number, 0, 255)));
|
|
164
169
|
}
|
|
165
170
|
|
|
166
171
|
Signature rgba_4_sig = "rgba($red, $green, $blue, $alpha)";
|
|
167
172
|
BUILT_IN(rgba_4)
|
|
168
173
|
{
|
|
169
|
-
return new (ctx.mem) Color(
|
|
170
|
-
|
|
171
|
-
ARGR("$
|
|
172
|
-
ARGR("$
|
|
173
|
-
ARGR("$blue", Number, 0, 255)->value(),
|
|
174
|
+
return new (ctx.mem) Color(pstate,
|
|
175
|
+
color_num(ARGR("$red", Number, 0, 255)),
|
|
176
|
+
color_num(ARGR("$green", Number, 0, 255)),
|
|
177
|
+
color_num(ARGR("$blue", Number, 0, 255)),
|
|
174
178
|
ARGR("$alpha", Number, 0, 1)->value());
|
|
175
179
|
}
|
|
176
180
|
|
|
@@ -186,15 +190,15 @@ namespace Sass {
|
|
|
186
190
|
|
|
187
191
|
Signature red_sig = "red($color)";
|
|
188
192
|
BUILT_IN(red)
|
|
189
|
-
{ return new (ctx.mem) Number(
|
|
193
|
+
{ return new (ctx.mem) Number(pstate, ARG("$color", Color)->r()); }
|
|
190
194
|
|
|
191
195
|
Signature green_sig = "green($color)";
|
|
192
196
|
BUILT_IN(green)
|
|
193
|
-
{ return new (ctx.mem) Number(
|
|
197
|
+
{ return new (ctx.mem) Number(pstate, ARG("$color", Color)->g()); }
|
|
194
198
|
|
|
195
199
|
Signature blue_sig = "blue($color)";
|
|
196
200
|
BUILT_IN(blue)
|
|
197
|
-
{ return new (ctx.mem) Number(
|
|
201
|
+
{ return new (ctx.mem) Number(pstate, ARG("$color", Color)->b()); }
|
|
198
202
|
|
|
199
203
|
Signature mix_sig = "mix($color-1, $color-2, $weight: 50%)";
|
|
200
204
|
BUILT_IN(mix)
|
|
@@ -210,8 +214,7 @@ namespace Sass {
|
|
|
210
214
|
double w1 = (((w * a == -1) ? w : (w + a)/(1 + w*a)) + 1)/2.0;
|
|
211
215
|
double w2 = 1 - w1;
|
|
212
216
|
|
|
213
|
-
return new (ctx.mem) Color(
|
|
214
|
-
position,
|
|
217
|
+
return new (ctx.mem) Color(pstate,
|
|
215
218
|
std::floor(w1*color1->r() + w2*color2->r()),
|
|
216
219
|
std::floor(w1*color1->g() + w2*color2->g()),
|
|
217
220
|
std::floor(w1*color1->b() + w2*color2->b()),
|
|
@@ -266,7 +269,7 @@ namespace Sass {
|
|
|
266
269
|
return m1;
|
|
267
270
|
}
|
|
268
271
|
|
|
269
|
-
Color* hsla_impl(double h, double s, double l, double a, Context& ctx,
|
|
272
|
+
Color* hsla_impl(double h, double s, double l, double a, Context& ctx, ParserState pstate)
|
|
270
273
|
{
|
|
271
274
|
h /= 360.0;
|
|
272
275
|
s /= 100.0;
|
|
@@ -282,7 +285,7 @@ namespace Sass {
|
|
|
282
285
|
double g = (h_to_rgb(m1, m2, h) * 255.0);
|
|
283
286
|
double b = (h_to_rgb(m1, m2, h-1.0/3.0) * 255.0);
|
|
284
287
|
|
|
285
|
-
return new (ctx.mem) Color(
|
|
288
|
+
return new (ctx.mem) Color(pstate, r, g, b, a);
|
|
286
289
|
}
|
|
287
290
|
|
|
288
291
|
Signature hsl_sig = "hsl($hue, $saturation, $lightness)";
|
|
@@ -293,8 +296,7 @@ namespace Sass {
|
|
|
293
296
|
ARGR("$lightness", Number, 0, 100)->value(),
|
|
294
297
|
1.0,
|
|
295
298
|
ctx,
|
|
296
|
-
|
|
297
|
-
position);
|
|
299
|
+
pstate);
|
|
298
300
|
}
|
|
299
301
|
|
|
300
302
|
Signature hsla_sig = "hsla($hue, $saturation, $lightness, $alpha)";
|
|
@@ -305,8 +307,7 @@ namespace Sass {
|
|
|
305
307
|
ARGR("$lightness", Number, 0, 100)->value(),
|
|
306
308
|
ARGR("$alpha", Number, 0, 1)->value(),
|
|
307
309
|
ctx,
|
|
308
|
-
|
|
309
|
-
position);
|
|
310
|
+
pstate);
|
|
310
311
|
}
|
|
311
312
|
|
|
312
313
|
Signature hue_sig = "hue($color)";
|
|
@@ -316,7 +317,7 @@ namespace Sass {
|
|
|
316
317
|
HSL hsl_color = rgb_to_hsl(rgb_color->r(),
|
|
317
318
|
rgb_color->g(),
|
|
318
319
|
rgb_color->b());
|
|
319
|
-
return new (ctx.mem) Number(
|
|
320
|
+
return new (ctx.mem) Number(pstate, hsl_color.h, "deg");
|
|
320
321
|
}
|
|
321
322
|
|
|
322
323
|
Signature saturation_sig = "saturation($color)";
|
|
@@ -326,7 +327,7 @@ namespace Sass {
|
|
|
326
327
|
HSL hsl_color = rgb_to_hsl(rgb_color->r(),
|
|
327
328
|
rgb_color->g(),
|
|
328
329
|
rgb_color->b());
|
|
329
|
-
return new (ctx.mem) Number(
|
|
330
|
+
return new (ctx.mem) Number(pstate, hsl_color.s, "%");
|
|
330
331
|
}
|
|
331
332
|
|
|
332
333
|
Signature lightness_sig = "lightness($color)";
|
|
@@ -336,7 +337,7 @@ namespace Sass {
|
|
|
336
337
|
HSL hsl_color = rgb_to_hsl(rgb_color->r(),
|
|
337
338
|
rgb_color->g(),
|
|
338
339
|
rgb_color->b());
|
|
339
|
-
return new (ctx.mem) Number(
|
|
340
|
+
return new (ctx.mem) Number(pstate, hsl_color.l, "%");
|
|
340
341
|
}
|
|
341
342
|
|
|
342
343
|
Signature adjust_hue_sig = "adjust-hue($color, $degrees)";
|
|
@@ -352,8 +353,7 @@ namespace Sass {
|
|
|
352
353
|
hsl_color.l,
|
|
353
354
|
rgb_color->a(),
|
|
354
355
|
ctx,
|
|
355
|
-
|
|
356
|
-
position);
|
|
356
|
+
pstate);
|
|
357
357
|
}
|
|
358
358
|
|
|
359
359
|
Signature lighten_sig = "lighten($color, $amount)";
|
|
@@ -375,8 +375,7 @@ namespace Sass {
|
|
|
375
375
|
hslcolorL + amount->value(),
|
|
376
376
|
rgb_color->a(),
|
|
377
377
|
ctx,
|
|
378
|
-
|
|
379
|
-
position);
|
|
378
|
+
pstate);
|
|
380
379
|
}
|
|
381
380
|
|
|
382
381
|
Signature darken_sig = "darken($color, $amount)";
|
|
@@ -399,8 +398,7 @@ namespace Sass {
|
|
|
399
398
|
hslcolorL - amount->value(),
|
|
400
399
|
rgb_color->a(),
|
|
401
400
|
ctx,
|
|
402
|
-
|
|
403
|
-
position);
|
|
401
|
+
pstate);
|
|
404
402
|
}
|
|
405
403
|
|
|
406
404
|
Signature saturate_sig = "saturate($color, $amount: false)";
|
|
@@ -410,7 +408,7 @@ namespace Sass {
|
|
|
410
408
|
Number* amount = dynamic_cast<Number*>(env["$amount"]);
|
|
411
409
|
if (!amount) {
|
|
412
410
|
To_String to_string(&ctx);
|
|
413
|
-
return new (ctx.mem) String_Constant(
|
|
411
|
+
return new (ctx.mem) String_Constant(pstate, "saturate(" + env["$color"]->perform(&to_string) + ")");
|
|
414
412
|
}
|
|
415
413
|
|
|
416
414
|
ARGR("$amount", Number, 0, 100);
|
|
@@ -418,20 +416,23 @@ namespace Sass {
|
|
|
418
416
|
HSL hsl_color = rgb_to_hsl(rgb_color->r(),
|
|
419
417
|
rgb_color->g(),
|
|
420
418
|
rgb_color->b());
|
|
421
|
-
|
|
422
|
-
double hslcolorS = hsl_color.s;
|
|
419
|
+
|
|
420
|
+
double hslcolorS = hsl_color.s + amount->value();
|
|
421
|
+
|
|
422
|
+
// Saturation cannot be below 0 or above 100
|
|
423
423
|
if (hslcolorS < 0) {
|
|
424
424
|
hslcolorS = 0;
|
|
425
425
|
}
|
|
426
|
-
|
|
426
|
+
if (hslcolorS > 100) {
|
|
427
|
+
hslcolorS = 100;
|
|
428
|
+
}
|
|
427
429
|
|
|
428
430
|
return hsla_impl(hsl_color.h,
|
|
429
|
-
hslcolorS
|
|
431
|
+
hslcolorS,
|
|
430
432
|
hsl_color.l,
|
|
431
433
|
rgb_color->a(),
|
|
432
434
|
ctx,
|
|
433
|
-
|
|
434
|
-
position);
|
|
435
|
+
pstate);
|
|
435
436
|
}
|
|
436
437
|
|
|
437
438
|
Signature desaturate_sig = "desaturate($color, $amount)";
|
|
@@ -442,19 +443,23 @@ namespace Sass {
|
|
|
442
443
|
HSL hsl_color = rgb_to_hsl(rgb_color->r(),
|
|
443
444
|
rgb_color->g(),
|
|
444
445
|
rgb_color->b());
|
|
445
|
-
|
|
446
|
-
double hslcolorS = hsl_color.s;
|
|
446
|
+
|
|
447
|
+
double hslcolorS = hsl_color.s - amount->value();
|
|
448
|
+
|
|
449
|
+
// Saturation cannot be below 0 or above 100
|
|
450
|
+
if (hslcolorS <= 0) {
|
|
451
|
+
hslcolorS = 0;
|
|
452
|
+
}
|
|
447
453
|
if (hslcolorS > 100) {
|
|
448
454
|
hslcolorS = 100;
|
|
449
455
|
}
|
|
450
456
|
|
|
451
457
|
return hsla_impl(hsl_color.h,
|
|
452
|
-
hslcolorS
|
|
458
|
+
hslcolorS,
|
|
453
459
|
hsl_color.l,
|
|
454
460
|
rgb_color->a(),
|
|
455
461
|
ctx,
|
|
456
|
-
|
|
457
|
-
position);
|
|
462
|
+
pstate);
|
|
458
463
|
}
|
|
459
464
|
|
|
460
465
|
Signature grayscale_sig = "grayscale($color)";
|
|
@@ -464,7 +469,7 @@ namespace Sass {
|
|
|
464
469
|
Number* amount = dynamic_cast<Number*>(env["$color"]);
|
|
465
470
|
if (amount) {
|
|
466
471
|
To_String to_string(&ctx);
|
|
467
|
-
return new (ctx.mem) String_Constant(
|
|
472
|
+
return new (ctx.mem) String_Constant(pstate, "grayscale(" + amount->perform(&to_string) + ")");
|
|
468
473
|
}
|
|
469
474
|
|
|
470
475
|
Color* rgb_color = ARG("$color", Color);
|
|
@@ -476,8 +481,7 @@ namespace Sass {
|
|
|
476
481
|
hsl_color.l,
|
|
477
482
|
rgb_color->a(),
|
|
478
483
|
ctx,
|
|
479
|
-
|
|
480
|
-
position);
|
|
484
|
+
pstate);
|
|
481
485
|
}
|
|
482
486
|
|
|
483
487
|
Signature complement_sig = "complement($color)";
|
|
@@ -492,8 +496,7 @@ namespace Sass {
|
|
|
492
496
|
hsl_color.l,
|
|
493
497
|
rgb_color->a(),
|
|
494
498
|
ctx,
|
|
495
|
-
|
|
496
|
-
position);
|
|
499
|
+
pstate);
|
|
497
500
|
}
|
|
498
501
|
|
|
499
502
|
Signature invert_sig = "invert($color)";
|
|
@@ -503,12 +506,11 @@ namespace Sass {
|
|
|
503
506
|
Number* amount = dynamic_cast<Number*>(env["$color"]);
|
|
504
507
|
if (amount) {
|
|
505
508
|
To_String to_string(&ctx);
|
|
506
|
-
return new (ctx.mem) String_Constant(
|
|
509
|
+
return new (ctx.mem) String_Constant(pstate, "invert(" + amount->perform(&to_string) + ")");
|
|
507
510
|
}
|
|
508
511
|
|
|
509
512
|
Color* rgb_color = ARG("$color", Color);
|
|
510
|
-
return new (ctx.mem) Color(
|
|
511
|
-
position,
|
|
513
|
+
return new (ctx.mem) Color(pstate,
|
|
512
514
|
255 - rgb_color->r(),
|
|
513
515
|
255 - rgb_color->g(),
|
|
514
516
|
255 - rgb_color->b(),
|
|
@@ -524,17 +526,17 @@ namespace Sass {
|
|
|
524
526
|
{
|
|
525
527
|
String_Constant* ie_kwd = dynamic_cast<String_Constant*>(env["$color"]);
|
|
526
528
|
if (ie_kwd) {
|
|
527
|
-
return new (ctx.mem) String_Constant(
|
|
529
|
+
return new (ctx.mem) String_Constant(pstate, "alpha(" + ie_kwd->value() + ")");
|
|
528
530
|
}
|
|
529
531
|
|
|
530
532
|
// CSS3 filter function overload: pass literal through directly
|
|
531
533
|
Number* amount = dynamic_cast<Number*>(env["$color"]);
|
|
532
534
|
if (amount) {
|
|
533
535
|
To_String to_string(&ctx);
|
|
534
|
-
return new (ctx.mem) String_Constant(
|
|
536
|
+
return new (ctx.mem) String_Constant(pstate, "opacity(" + amount->perform(&to_string) + ")");
|
|
535
537
|
}
|
|
536
538
|
|
|
537
|
-
return new (ctx.mem) Number(
|
|
539
|
+
return new (ctx.mem) Number(pstate, ARG("$color", Color)->a());
|
|
538
540
|
}
|
|
539
541
|
|
|
540
542
|
Signature opacify_sig = "opacify($color, $amount)";
|
|
@@ -542,13 +544,13 @@ namespace Sass {
|
|
|
542
544
|
BUILT_IN(opacify)
|
|
543
545
|
{
|
|
544
546
|
Color* color = ARG("$color", Color);
|
|
545
|
-
double
|
|
546
|
-
|
|
547
|
-
|
|
547
|
+
double amount = ARGR("$amount", Number, 0, 1)->value();
|
|
548
|
+
double alpha = std::min(color->a() + amount, 1.0);
|
|
549
|
+
return new (ctx.mem) Color(pstate,
|
|
548
550
|
color->r(),
|
|
549
551
|
color->g(),
|
|
550
552
|
color->b(),
|
|
551
|
-
alpha
|
|
553
|
+
alpha);
|
|
552
554
|
}
|
|
553
555
|
|
|
554
556
|
Signature transparentize_sig = "transparentize($color, $amount)";
|
|
@@ -556,13 +558,13 @@ namespace Sass {
|
|
|
556
558
|
BUILT_IN(transparentize)
|
|
557
559
|
{
|
|
558
560
|
Color* color = ARG("$color", Color);
|
|
559
|
-
double
|
|
560
|
-
|
|
561
|
-
|
|
561
|
+
double amount = ARGR("$amount", Number, 0, 1)->value();
|
|
562
|
+
double alpha = std::max(color->a() - amount, 0.0);
|
|
563
|
+
return new (ctx.mem) Color(pstate,
|
|
562
564
|
color->r(),
|
|
563
565
|
color->g(),
|
|
564
566
|
color->b(),
|
|
565
|
-
alpha
|
|
567
|
+
alpha);
|
|
566
568
|
}
|
|
567
569
|
|
|
568
570
|
////////////////////////
|
|
@@ -585,11 +587,10 @@ namespace Sass {
|
|
|
585
587
|
bool hsl = h || s || l;
|
|
586
588
|
|
|
587
589
|
if (rgb && hsl) {
|
|
588
|
-
error("cannot specify both RGB and HSL values for `adjust-color`",
|
|
590
|
+
error("cannot specify both RGB and HSL values for `adjust-color`", pstate);
|
|
589
591
|
}
|
|
590
592
|
if (rgb) {
|
|
591
|
-
return new (ctx.mem) Color(
|
|
592
|
-
position,
|
|
593
|
+
return new (ctx.mem) Color(pstate,
|
|
593
594
|
color->r() + (r ? r->value() : 0),
|
|
594
595
|
color->g() + (g ? g->value() : 0),
|
|
595
596
|
color->b() + (b ? b->value() : 0),
|
|
@@ -602,18 +603,16 @@ namespace Sass {
|
|
|
602
603
|
hsl_struct.l + (l ? l->value() : 0),
|
|
603
604
|
color->a() + (a ? a->value() : 0),
|
|
604
605
|
ctx,
|
|
605
|
-
|
|
606
|
-
position);
|
|
606
|
+
pstate);
|
|
607
607
|
}
|
|
608
608
|
if (a) {
|
|
609
|
-
return new (ctx.mem) Color(
|
|
610
|
-
position,
|
|
609
|
+
return new (ctx.mem) Color(pstate,
|
|
611
610
|
color->r(),
|
|
612
611
|
color->g(),
|
|
613
612
|
color->b(),
|
|
614
613
|
color->a() + (a ? a->value() : 0));
|
|
615
614
|
}
|
|
616
|
-
error("not enough arguments for `adjust-color`",
|
|
615
|
+
error("not enough arguments for `adjust-color`", pstate);
|
|
617
616
|
// unreachable
|
|
618
617
|
return color;
|
|
619
618
|
}
|
|
@@ -634,15 +633,14 @@ namespace Sass {
|
|
|
634
633
|
bool hsl = h || s || l;
|
|
635
634
|
|
|
636
635
|
if (rgb && hsl) {
|
|
637
|
-
error("cannot specify both RGB and HSL values for `scale-color`",
|
|
636
|
+
error("cannot specify both RGB and HSL values for `scale-color`", pstate);
|
|
638
637
|
}
|
|
639
638
|
if (rgb) {
|
|
640
639
|
double rscale = (r ? ARGR("$red", Number, -100.0, 100.0)->value() : 0.0) / 100.0;
|
|
641
640
|
double gscale = (g ? ARGR("$green", Number, -100.0, 100.0)->value() : 0.0) / 100.0;
|
|
642
641
|
double bscale = (b ? ARGR("$blue", Number, -100.0, 100.0)->value() : 0.0) / 100.0;
|
|
643
642
|
double ascale = (a ? ARGR("$alpha", Number, -100.0, 100.0)->value() : 0.0) / 100.0;
|
|
644
|
-
return new (ctx.mem) Color(
|
|
645
|
-
position,
|
|
643
|
+
return new (ctx.mem) Color(pstate,
|
|
646
644
|
color->r() + rscale * (rscale > 0.0 ? 255 - color->r() : color->r()),
|
|
647
645
|
color->g() + gscale * (gscale > 0.0 ? 255 - color->g() : color->g()),
|
|
648
646
|
color->b() + bscale * (bscale > 0.0 ? 255 - color->b() : color->b()),
|
|
@@ -657,19 +655,18 @@ namespace Sass {
|
|
|
657
655
|
hsl_struct.h += hscale * (hscale > 0.0 ? 360.0 - hsl_struct.h : hsl_struct.h);
|
|
658
656
|
hsl_struct.s += sscale * (sscale > 0.0 ? 100.0 - hsl_struct.s : hsl_struct.s);
|
|
659
657
|
hsl_struct.l += lscale * (lscale > 0.0 ? 100.0 - hsl_struct.l : hsl_struct.l);
|
|
660
|
-
double alpha = color->a() + ascale * (ascale > 0.0 ? 1.0 - color->a() : color->
|
|
661
|
-
return hsla_impl(hsl_struct.h, hsl_struct.s, hsl_struct.l, alpha, ctx,
|
|
658
|
+
double alpha = color->a() + ascale * (ascale > 0.0 ? 1.0 - color->a() : color->a());
|
|
659
|
+
return hsla_impl(hsl_struct.h, hsl_struct.s, hsl_struct.l, alpha, ctx, pstate);
|
|
662
660
|
}
|
|
663
661
|
if (a) {
|
|
664
662
|
double ascale = (a ? ARGR("$alpha", Number, -100.0, 100.0)->value() : 0.0) / 100.0;
|
|
665
|
-
return new (ctx.mem) Color(
|
|
666
|
-
position,
|
|
663
|
+
return new (ctx.mem) Color(pstate,
|
|
667
664
|
color->r(),
|
|
668
665
|
color->g(),
|
|
669
666
|
color->b(),
|
|
670
667
|
color->a() + ascale * (ascale > 0.0 ? 1.0 - color->a() : color->a()));
|
|
671
668
|
}
|
|
672
|
-
error("not enough arguments for `scale-color`",
|
|
669
|
+
error("not enough arguments for `scale-color`", pstate);
|
|
673
670
|
// unreachable
|
|
674
671
|
return color;
|
|
675
672
|
}
|
|
@@ -690,11 +687,10 @@ namespace Sass {
|
|
|
690
687
|
bool hsl = h || s || l;
|
|
691
688
|
|
|
692
689
|
if (rgb && hsl) {
|
|
693
|
-
error("cannot specify both RGB and HSL values for `change-color`",
|
|
690
|
+
error("cannot specify both RGB and HSL values for `change-color`", pstate);
|
|
694
691
|
}
|
|
695
692
|
if (rgb) {
|
|
696
|
-
return new (ctx.mem) Color(
|
|
697
|
-
position,
|
|
693
|
+
return new (ctx.mem) Color(pstate,
|
|
698
694
|
r ? ARGR("$red", Number, 0, 255)->value() : color->r(),
|
|
699
695
|
g ? ARGR("$green", Number, 0, 255)->value() : color->g(),
|
|
700
696
|
b ? ARGR("$blue", Number, 0, 255)->value() : color->b(),
|
|
@@ -706,18 +702,17 @@ namespace Sass {
|
|
|
706
702
|
if (s) hsl_struct.s = ARGR("$saturation", Number, 0, 100)->value();
|
|
707
703
|
if (l) hsl_struct.l = ARGR("$lightness", Number, 0, 100)->value();
|
|
708
704
|
double alpha = a ? ARGR("$alpha", Number, 0, 1.0)->value() : color->a();
|
|
709
|
-
return hsla_impl(hsl_struct.h, hsl_struct.s, hsl_struct.l, alpha, ctx,
|
|
705
|
+
return hsla_impl(hsl_struct.h, hsl_struct.s, hsl_struct.l, alpha, ctx, pstate);
|
|
710
706
|
}
|
|
711
707
|
if (a) {
|
|
712
708
|
double alpha = a ? ARGR("$alpha", Number, 0, 1.0)->value() : color->a();
|
|
713
|
-
return new (ctx.mem) Color(
|
|
714
|
-
position,
|
|
709
|
+
return new (ctx.mem) Color(pstate,
|
|
715
710
|
color->r(),
|
|
716
711
|
color->g(),
|
|
717
712
|
color->b(),
|
|
718
713
|
alpha);
|
|
719
714
|
}
|
|
720
|
-
error("not enough arguments for `change-color`",
|
|
715
|
+
error("not enough arguments for `change-color`", pstate);
|
|
721
716
|
// unreachable
|
|
722
717
|
return color;
|
|
723
718
|
}
|
|
@@ -749,7 +744,7 @@ namespace Sass {
|
|
|
749
744
|
for (size_t i = 0, L = result.length(); i < L; ++i) {
|
|
750
745
|
result[i] = std::toupper(result[i]);
|
|
751
746
|
}
|
|
752
|
-
return new (ctx.mem) String_Constant(
|
|
747
|
+
return new (ctx.mem) String_Constant(pstate, result);
|
|
753
748
|
}
|
|
754
749
|
|
|
755
750
|
///////////////////
|
|
@@ -759,24 +754,24 @@ namespace Sass {
|
|
|
759
754
|
Signature unquote_sig = "unquote($string)";
|
|
760
755
|
BUILT_IN(sass_unquote)
|
|
761
756
|
{
|
|
762
|
-
To_String to_string;
|
|
757
|
+
To_String to_string(&ctx);
|
|
763
758
|
AST_Node* arg = env["$string"];
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
return
|
|
759
|
+
if (String_Quoted* string_quoted = dynamic_cast<String_Quoted*>(arg)) {
|
|
760
|
+
String_Constant* result = new (ctx.mem) String_Constant(pstate, string_quoted->value());
|
|
761
|
+
// remember if the string was quoted (color tokens)
|
|
762
|
+
result->sass_fix_1291(string_quoted->quote_mark() != 0);
|
|
763
|
+
return result;
|
|
764
|
+
}
|
|
765
|
+
return new (ctx.mem) String_Constant(pstate, string(arg->perform(&to_string)));
|
|
771
766
|
}
|
|
772
767
|
|
|
773
768
|
Signature quote_sig = "quote($string)";
|
|
774
769
|
BUILT_IN(sass_quote)
|
|
775
770
|
{
|
|
776
|
-
To_String to_string;
|
|
771
|
+
To_String to_string(&ctx);
|
|
777
772
|
AST_Node* arg = env["$string"];
|
|
778
773
|
string str(quote(arg->perform(&to_string), String_Constant::double_quote()));
|
|
779
|
-
String_Constant* result = new (ctx.mem) String_Constant(
|
|
774
|
+
String_Constant* result = new (ctx.mem) String_Constant(pstate, str);
|
|
780
775
|
result->is_delayed(true);
|
|
781
776
|
return result;
|
|
782
777
|
}
|
|
@@ -788,33 +783,24 @@ namespace Sass {
|
|
|
788
783
|
size_t len = string::npos;
|
|
789
784
|
try {
|
|
790
785
|
String_Constant* s = ARG("$string", String_Constant);
|
|
791
|
-
|
|
792
|
-
size_t length_of_s = str.size();
|
|
793
|
-
size_t i = 0;
|
|
794
|
-
|
|
795
|
-
if (s->is_quoted()) {
|
|
796
|
-
++i;
|
|
797
|
-
--length_of_s;
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
len = UTF_8::code_point_count(str, i, length_of_s);
|
|
786
|
+
len = UTF_8::code_point_count(s->value(), 0, s->value().size());
|
|
801
787
|
|
|
802
788
|
}
|
|
803
789
|
catch (utf8::invalid_code_point) {
|
|
804
790
|
string msg("utf8::invalid_code_point");
|
|
805
|
-
error(msg,
|
|
791
|
+
error(msg, pstate, backtrace);
|
|
806
792
|
}
|
|
807
793
|
catch (utf8::not_enough_room) {
|
|
808
794
|
string msg("utf8::not_enough_room");
|
|
809
|
-
error(msg,
|
|
795
|
+
error(msg, pstate, backtrace);
|
|
810
796
|
}
|
|
811
797
|
catch (utf8::invalid_utf8) {
|
|
812
798
|
string msg("utf8::invalid_utf8");
|
|
813
|
-
error(msg,
|
|
799
|
+
error(msg, pstate, backtrace);
|
|
814
800
|
}
|
|
815
801
|
catch (...) { throw; }
|
|
816
802
|
// return something even if we had an error (-1)
|
|
817
|
-
return new (ctx.mem) Number(
|
|
803
|
+
return new (ctx.mem) Number(pstate, len);
|
|
818
804
|
}
|
|
819
805
|
|
|
820
806
|
Signature str_insert_sig = "str-insert($string, $insert, $index)";
|
|
@@ -824,7 +810,6 @@ namespace Sass {
|
|
|
824
810
|
try {
|
|
825
811
|
String_Constant* s = ARG("$string", String_Constant);
|
|
826
812
|
str = s->value();
|
|
827
|
-
char quotemark = s->quote_mark();
|
|
828
813
|
str = unquote(str);
|
|
829
814
|
String_Constant* i = ARG("$insert", String_Constant);
|
|
830
815
|
string ins = i->value();
|
|
@@ -835,7 +820,7 @@ namespace Sass {
|
|
|
835
820
|
|
|
836
821
|
if (index > 0 && index <= len) {
|
|
837
822
|
// positive and within string length
|
|
838
|
-
str.insert(UTF_8::offset_at_position(str, index - 1), ins);
|
|
823
|
+
str.insert(UTF_8::offset_at_position(str, static_cast<size_t>(index) - 1), ins);
|
|
839
824
|
}
|
|
840
825
|
else if (index > len) {
|
|
841
826
|
// positive and past string length
|
|
@@ -847,31 +832,31 @@ namespace Sass {
|
|
|
847
832
|
else if (std::abs(index) <= len) {
|
|
848
833
|
// negative and within string length
|
|
849
834
|
index += len + 1;
|
|
850
|
-
str.insert(UTF_8::offset_at_position(str, index), ins);
|
|
835
|
+
str.insert(UTF_8::offset_at_position(str, static_cast<size_t>(index)), ins);
|
|
851
836
|
}
|
|
852
837
|
else {
|
|
853
838
|
// negative and past string length
|
|
854
839
|
str = ins + str;
|
|
855
840
|
}
|
|
856
841
|
|
|
857
|
-
if (
|
|
858
|
-
str = quote(str
|
|
842
|
+
if (String_Quoted* ss = dynamic_cast<String_Quoted*>(s)) {
|
|
843
|
+
if (ss->quote_mark()) str = quote(str);
|
|
859
844
|
}
|
|
860
845
|
}
|
|
861
846
|
catch (utf8::invalid_code_point) {
|
|
862
847
|
string msg("utf8::invalid_code_point");
|
|
863
|
-
error(msg,
|
|
848
|
+
error(msg, pstate, backtrace);
|
|
864
849
|
}
|
|
865
850
|
catch (utf8::not_enough_room) {
|
|
866
851
|
string msg("utf8::not_enough_room");
|
|
867
|
-
error(msg,
|
|
852
|
+
error(msg, pstate, backtrace);
|
|
868
853
|
}
|
|
869
854
|
catch (utf8::invalid_utf8) {
|
|
870
855
|
string msg("utf8::invalid_utf8");
|
|
871
|
-
error(msg,
|
|
856
|
+
error(msg, pstate, backtrace);
|
|
872
857
|
}
|
|
873
858
|
catch (...) { throw; }
|
|
874
|
-
return new (ctx.mem) String_Constant(
|
|
859
|
+
return new (ctx.mem) String_Constant(pstate, str);
|
|
875
860
|
}
|
|
876
861
|
|
|
877
862
|
Signature str_index_sig = "str-index($string, $substring)";
|
|
@@ -888,25 +873,25 @@ namespace Sass {
|
|
|
888
873
|
|
|
889
874
|
size_t c_index = str.find(substr);
|
|
890
875
|
if(c_index == string::npos) {
|
|
891
|
-
return new (ctx.mem) Null(
|
|
876
|
+
return new (ctx.mem) Null(pstate);
|
|
892
877
|
}
|
|
893
878
|
index = UTF_8::code_point_count(str, 0, c_index) + 1;
|
|
894
879
|
}
|
|
895
880
|
catch (utf8::invalid_code_point) {
|
|
896
881
|
string msg("utf8::invalid_code_point");
|
|
897
|
-
error(msg,
|
|
882
|
+
error(msg, pstate, backtrace);
|
|
898
883
|
}
|
|
899
884
|
catch (utf8::not_enough_room) {
|
|
900
885
|
string msg("utf8::not_enough_room");
|
|
901
|
-
error(msg,
|
|
886
|
+
error(msg, pstate, backtrace);
|
|
902
887
|
}
|
|
903
888
|
catch (utf8::invalid_utf8) {
|
|
904
889
|
string msg("utf8::invalid_utf8");
|
|
905
|
-
error(msg,
|
|
890
|
+
error(msg, pstate, backtrace);
|
|
906
891
|
}
|
|
907
892
|
catch (...) { throw; }
|
|
908
893
|
// return something even if we had an error (-1)
|
|
909
|
-
return new (ctx.mem) Number(
|
|
894
|
+
return new (ctx.mem) Number(pstate, index);
|
|
910
895
|
}
|
|
911
896
|
|
|
912
897
|
Signature str_slice_sig = "str-slice($string, $start-at, $end-at:-1)";
|
|
@@ -918,39 +903,44 @@ namespace Sass {
|
|
|
918
903
|
Number* n = ARG("$start-at", Number);
|
|
919
904
|
Number* m = ARG("$end-at", Number);
|
|
920
905
|
|
|
921
|
-
string str = s->value();
|
|
922
|
-
char quotemark = s->quote_mark();
|
|
923
|
-
str = unquote(str);
|
|
906
|
+
string str = unquote(s->value());
|
|
924
907
|
|
|
925
908
|
// normalize into 0-based indices
|
|
926
|
-
size_t start = UTF_8::offset_at_position(str, UTF_8::normalize_index(n->value(), UTF_8::code_point_count(str)));
|
|
927
|
-
size_t end = UTF_8::offset_at_position(str, UTF_8::normalize_index(m->value(), UTF_8::code_point_count(str)));
|
|
909
|
+
size_t start = UTF_8::offset_at_position(str, UTF_8::normalize_index(static_cast<int>(n->value()), UTF_8::code_point_count(str)));
|
|
910
|
+
size_t end = UTF_8::offset_at_position(str, UTF_8::normalize_index(static_cast<int>(m->value()), UTF_8::code_point_count(str)));
|
|
928
911
|
|
|
929
912
|
// `str-slice` should always return an empty string when $end-at == 0
|
|
930
913
|
// `normalize_index` normalizes 1 -> 0 so we need to check the original value
|
|
931
|
-
if(
|
|
914
|
+
if(m->value() == 0) {
|
|
915
|
+
if (String_Quoted* ss = dynamic_cast<String_Quoted*>(s)) {
|
|
916
|
+
if(!ss->quote_mark()) return new (ctx.mem) Null(pstate);
|
|
917
|
+
} else {
|
|
918
|
+
return new (ctx.mem) Null(pstate);
|
|
919
|
+
}
|
|
920
|
+
newstr = "";
|
|
921
|
+
} else if(start == end && m->value() != 0) {
|
|
932
922
|
newstr = str.substr(start, 1);
|
|
933
923
|
} else if(end > start) {
|
|
934
924
|
newstr = str.substr(start, end - start + UTF_8::code_point_size_at_offset(str, end));
|
|
935
925
|
}
|
|
936
|
-
if(
|
|
937
|
-
newstr = quote(newstr
|
|
926
|
+
if (String_Quoted* ss = dynamic_cast<String_Quoted*>(s)) {
|
|
927
|
+
if(ss->quote_mark()) newstr = quote(newstr);
|
|
938
928
|
}
|
|
939
929
|
}
|
|
940
930
|
catch (utf8::invalid_code_point) {
|
|
941
931
|
string msg("utf8::invalid_code_point");
|
|
942
|
-
error(msg,
|
|
932
|
+
error(msg, pstate, backtrace);
|
|
943
933
|
}
|
|
944
934
|
catch (utf8::not_enough_room) {
|
|
945
935
|
string msg("utf8::not_enough_room");
|
|
946
|
-
error(msg,
|
|
936
|
+
error(msg, pstate, backtrace);
|
|
947
937
|
}
|
|
948
938
|
catch (utf8::invalid_utf8) {
|
|
949
939
|
string msg("utf8::invalid_utf8");
|
|
950
|
-
error(msg,
|
|
940
|
+
error(msg, pstate, backtrace);
|
|
951
941
|
}
|
|
952
942
|
catch (...) { throw; }
|
|
953
|
-
return new (ctx.mem) String_Constant(
|
|
943
|
+
return new (ctx.mem) String_Constant(pstate, newstr);
|
|
954
944
|
}
|
|
955
945
|
|
|
956
946
|
Signature to_upper_case_sig = "to-upper-case($string)";
|
|
@@ -965,7 +955,10 @@ namespace Sass {
|
|
|
965
955
|
}
|
|
966
956
|
}
|
|
967
957
|
|
|
968
|
-
|
|
958
|
+
if (String_Quoted* ss = dynamic_cast<String_Quoted*>(s)) {
|
|
959
|
+
str = ss->quote_mark() ? quote(str) : str;
|
|
960
|
+
}
|
|
961
|
+
return new (ctx.mem) String_Constant(pstate, str);
|
|
969
962
|
}
|
|
970
963
|
|
|
971
964
|
Signature to_lower_case_sig = "to-lower-case($string)";
|
|
@@ -980,89 +973,90 @@ namespace Sass {
|
|
|
980
973
|
}
|
|
981
974
|
}
|
|
982
975
|
|
|
983
|
-
|
|
976
|
+
if (String_Quoted* ss = dynamic_cast<String_Quoted*>(s)) {
|
|
977
|
+
str = ss->quote_mark() ? quote(str, '"') : str;
|
|
978
|
+
}
|
|
979
|
+
return new (ctx.mem) String_Constant(pstate, str);
|
|
984
980
|
}
|
|
985
981
|
|
|
986
982
|
///////////////////
|
|
987
983
|
// NUMBER FUNCTIONS
|
|
988
984
|
///////////////////
|
|
989
985
|
|
|
990
|
-
Signature percentage_sig = "percentage($
|
|
986
|
+
Signature percentage_sig = "percentage($number)";
|
|
991
987
|
BUILT_IN(percentage)
|
|
992
988
|
{
|
|
993
|
-
Number* n = ARG("$
|
|
994
|
-
if (!n->is_unitless()) error("argument $
|
|
995
|
-
return new (ctx.mem) Number(
|
|
989
|
+
Number* n = ARG("$number", Number);
|
|
990
|
+
if (!n->is_unitless()) error("argument $number of `" + string(sig) + "` must be unitless", pstate);
|
|
991
|
+
return new (ctx.mem) Number(pstate, n->value() * 100, "%");
|
|
996
992
|
}
|
|
997
993
|
|
|
998
|
-
Signature round_sig = "round($
|
|
994
|
+
Signature round_sig = "round($number)";
|
|
999
995
|
BUILT_IN(round)
|
|
1000
996
|
{
|
|
1001
|
-
Number* n = ARG("$
|
|
997
|
+
Number* n = ARG("$number", Number);
|
|
1002
998
|
Number* r = new (ctx.mem) Number(*n);
|
|
1003
|
-
r->
|
|
1004
|
-
r->position(position);
|
|
999
|
+
r->pstate(pstate);
|
|
1005
1000
|
r->value(std::floor(r->value() + 0.5));
|
|
1006
1001
|
return r;
|
|
1007
1002
|
}
|
|
1008
1003
|
|
|
1009
|
-
Signature ceil_sig = "ceil($
|
|
1004
|
+
Signature ceil_sig = "ceil($number)";
|
|
1010
1005
|
BUILT_IN(ceil)
|
|
1011
1006
|
{
|
|
1012
|
-
Number* n = ARG("$
|
|
1007
|
+
Number* n = ARG("$number", Number);
|
|
1013
1008
|
Number* r = new (ctx.mem) Number(*n);
|
|
1014
|
-
r->
|
|
1015
|
-
r->position(position);
|
|
1009
|
+
r->pstate(pstate);
|
|
1016
1010
|
r->value(std::ceil(r->value()));
|
|
1017
1011
|
return r;
|
|
1018
1012
|
}
|
|
1019
1013
|
|
|
1020
|
-
Signature floor_sig = "floor($
|
|
1014
|
+
Signature floor_sig = "floor($number)";
|
|
1021
1015
|
BUILT_IN(floor)
|
|
1022
1016
|
{
|
|
1023
|
-
Number* n = ARG("$
|
|
1017
|
+
Number* n = ARG("$number", Number);
|
|
1024
1018
|
Number* r = new (ctx.mem) Number(*n);
|
|
1025
|
-
r->
|
|
1026
|
-
r->position(position);
|
|
1019
|
+
r->pstate(pstate);
|
|
1027
1020
|
r->value(std::floor(r->value()));
|
|
1028
1021
|
return r;
|
|
1029
1022
|
}
|
|
1030
1023
|
|
|
1031
|
-
Signature abs_sig = "abs($
|
|
1024
|
+
Signature abs_sig = "abs($number)";
|
|
1032
1025
|
BUILT_IN(abs)
|
|
1033
1026
|
{
|
|
1034
|
-
Number* n = ARG("$
|
|
1027
|
+
Number* n = ARG("$number", Number);
|
|
1035
1028
|
Number* r = new (ctx.mem) Number(*n);
|
|
1036
|
-
r->
|
|
1037
|
-
r->position(position);
|
|
1029
|
+
r->pstate(pstate);
|
|
1038
1030
|
r->value(std::abs(r->value()));
|
|
1039
1031
|
return r;
|
|
1040
1032
|
}
|
|
1041
1033
|
|
|
1042
|
-
Signature min_sig = "min($
|
|
1034
|
+
Signature min_sig = "min($numbers...)";
|
|
1043
1035
|
BUILT_IN(min)
|
|
1044
1036
|
{
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
Number* least = x1;
|
|
1037
|
+
List* arglist = ARG("$numbers", List);
|
|
1038
|
+
Number* least = 0;
|
|
1048
1039
|
for (size_t i = 0, L = arglist->length(); i < L; ++i) {
|
|
1049
1040
|
Number* xi = dynamic_cast<Number*>(arglist->value_at_index(i));
|
|
1050
|
-
if (
|
|
1051
|
-
|
|
1041
|
+
if (least) {
|
|
1042
|
+
if (!xi) error("`" + string(sig) + "` only takes numeric arguments", pstate);
|
|
1043
|
+
if (lt(xi, least, ctx)) least = xi;
|
|
1044
|
+
} else least = xi;
|
|
1052
1045
|
}
|
|
1053
1046
|
return least;
|
|
1054
1047
|
}
|
|
1055
1048
|
|
|
1056
|
-
Signature max_sig = "max($
|
|
1049
|
+
Signature max_sig = "max($numbers...)";
|
|
1057
1050
|
BUILT_IN(max)
|
|
1058
1051
|
{
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
Number* greatest = x1;
|
|
1052
|
+
List* arglist = ARG("$numbers", List);
|
|
1053
|
+
Number* greatest = 0;
|
|
1062
1054
|
for (size_t i = 0, L = arglist->length(); i < L; ++i) {
|
|
1063
1055
|
Number* xi = dynamic_cast<Number*>(arglist->value_at_index(i));
|
|
1064
|
-
if (
|
|
1065
|
-
|
|
1056
|
+
if (greatest) {
|
|
1057
|
+
if (!xi) error("`" + string(sig) + "` only takes numeric arguments", pstate);
|
|
1058
|
+
if (lt(greatest, xi, ctx)) greatest = xi;
|
|
1059
|
+
} else greatest = xi;
|
|
1066
1060
|
}
|
|
1067
1061
|
return greatest;
|
|
1068
1062
|
}
|
|
@@ -1071,16 +1065,16 @@ namespace Sass {
|
|
|
1071
1065
|
BUILT_IN(random)
|
|
1072
1066
|
{
|
|
1073
1067
|
Number* l = dynamic_cast<Number*>(env["$limit"]);
|
|
1074
|
-
if (l && trunc(l->value()) != l->value()) error("argument $limit of `" + string(sig) + "` must be an integer",
|
|
1068
|
+
if (l && trunc(l->value()) != l->value()) error("argument $limit of `" + string(sig) + "` must be an integer", pstate);
|
|
1075
1069
|
if (l) {
|
|
1076
1070
|
uniform_real_distribution<> distributor(1, l->value() + 1);
|
|
1077
|
-
uint_fast32_t distributed = distributor(rand);
|
|
1078
|
-
return new (ctx.mem) Number(
|
|
1071
|
+
uint_fast32_t distributed = static_cast<uint_fast32_t>(distributor(rand));
|
|
1072
|
+
return new (ctx.mem) Number(pstate, (double)distributed);
|
|
1079
1073
|
}
|
|
1080
1074
|
else {
|
|
1081
1075
|
uniform_real_distribution<> distributor(0, 1);
|
|
1082
|
-
uint_fast32_t distributed = distributor(rand);
|
|
1083
|
-
return new (ctx.mem) Number(
|
|
1076
|
+
uint_fast32_t distributed = static_cast<uint_fast32_t>(distributor(rand));
|
|
1077
|
+
return new (ctx.mem) Number(pstate, trunc(distributed));
|
|
1084
1078
|
}
|
|
1085
1079
|
}
|
|
1086
1080
|
|
|
@@ -1094,14 +1088,12 @@ namespace Sass {
|
|
|
1094
1088
|
Expression* v = ARG("$list", Expression);
|
|
1095
1089
|
if (v->concrete_type() == Expression::MAP) {
|
|
1096
1090
|
Map* map = dynamic_cast<Map*>(env["$list"]);
|
|
1097
|
-
return new (ctx.mem) Number(
|
|
1098
|
-
position,
|
|
1091
|
+
return new (ctx.mem) Number(pstate,
|
|
1099
1092
|
map ? map->length() : 1);
|
|
1100
1093
|
}
|
|
1101
1094
|
|
|
1102
1095
|
List* list = dynamic_cast<List*>(env["$list"]);
|
|
1103
|
-
return new (ctx.mem) Number(
|
|
1104
|
-
position,
|
|
1096
|
+
return new (ctx.mem) Number(pstate,
|
|
1105
1097
|
list ? list->length() : 1);
|
|
1106
1098
|
}
|
|
1107
1099
|
|
|
@@ -1111,26 +1103,26 @@ namespace Sass {
|
|
|
1111
1103
|
Map* m = dynamic_cast<Map*>(env["$list"]);
|
|
1112
1104
|
List* l = dynamic_cast<List*>(env["$list"]);
|
|
1113
1105
|
Number* n = ARG("$n", Number);
|
|
1114
|
-
if (n->value() == 0) error("argument `$n` of `" + string(sig) + "` must be non-zero",
|
|
1106
|
+
if (n->value() == 0) error("argument `$n` of `" + string(sig) + "` must be non-zero", pstate);
|
|
1115
1107
|
// if the argument isn't a list, then wrap it in a singleton list
|
|
1116
1108
|
if (!m && !l) {
|
|
1117
|
-
l = new (ctx.mem) List(
|
|
1109
|
+
l = new (ctx.mem) List(pstate, 1);
|
|
1118
1110
|
*l << ARG("$list", Expression);
|
|
1119
1111
|
}
|
|
1120
1112
|
size_t len = m ? m->length() : l->length();
|
|
1121
1113
|
bool empty = m ? m->empty() : l->empty();
|
|
1122
|
-
if (empty) error("argument `$list` of `" + string(sig) + "` must not be empty",
|
|
1114
|
+
if (empty) error("argument `$list` of `" + string(sig) + "` must not be empty", pstate);
|
|
1123
1115
|
double index = std::floor(n->value() < 0 ? len + n->value() : n->value() - 1);
|
|
1124
|
-
if (index < 0 || index > len - 1) error("index out of bounds for `" + string(sig) + "`",
|
|
1116
|
+
if (index < 0 || index > len - 1) error("index out of bounds for `" + string(sig) + "`", pstate);
|
|
1125
1117
|
|
|
1126
1118
|
if (m) {
|
|
1127
|
-
l = new (ctx.mem) List(
|
|
1128
|
-
*l << m->keys()[index];
|
|
1129
|
-
*l << m->at(m->keys()[index]);
|
|
1119
|
+
l = new (ctx.mem) List(pstate, 1);
|
|
1120
|
+
*l << m->keys()[static_cast<unsigned int>(index)];
|
|
1121
|
+
*l << m->at(m->keys()[static_cast<unsigned int>(index)]);
|
|
1130
1122
|
return l;
|
|
1131
1123
|
}
|
|
1132
1124
|
else {
|
|
1133
|
-
return l->value_at_index(index);
|
|
1125
|
+
return l->value_at_index(static_cast<int>(index));
|
|
1134
1126
|
}
|
|
1135
1127
|
}
|
|
1136
1128
|
|
|
@@ -1141,13 +1133,13 @@ namespace Sass {
|
|
|
1141
1133
|
Number* n = ARG("$n", Number);
|
|
1142
1134
|
Expression* v = ARG("$value", Expression);
|
|
1143
1135
|
if (!l) {
|
|
1144
|
-
l = new (ctx.mem) List(
|
|
1136
|
+
l = new (ctx.mem) List(pstate, 1);
|
|
1145
1137
|
*l << ARG("$list", Expression);
|
|
1146
1138
|
}
|
|
1147
|
-
if (l->empty()) error("argument `$list` of `" + string(sig) + "` must not be empty",
|
|
1139
|
+
if (l->empty()) error("argument `$list` of `" + string(sig) + "` must not be empty", pstate);
|
|
1148
1140
|
double index = std::floor(n->value() < 0 ? l->length() + n->value() : n->value() - 1);
|
|
1149
|
-
if (index < 0 || index > l->length() - 1) error("index out of bounds for `" + string(sig) + "`",
|
|
1150
|
-
List* result = new (ctx.mem) List(
|
|
1141
|
+
if (index < 0 || index > l->length() - 1) error("index out of bounds for `" + string(sig) + "`", pstate);
|
|
1142
|
+
List* result = new (ctx.mem) List(pstate, l->length(), l->separator());
|
|
1151
1143
|
for (size_t i = 0, L = l->length(); i < L; ++i) {
|
|
1152
1144
|
*result << ((i == index) ? v : (*l)[i]);
|
|
1153
1145
|
}
|
|
@@ -1160,13 +1152,13 @@ namespace Sass {
|
|
|
1160
1152
|
List* l = dynamic_cast<List*>(env["$list"]);
|
|
1161
1153
|
Expression* v = ARG("$value", Expression);
|
|
1162
1154
|
if (!l) {
|
|
1163
|
-
l = new (ctx.mem) List(
|
|
1155
|
+
l = new (ctx.mem) List(pstate, 1);
|
|
1164
1156
|
*l << ARG("$list", Expression);
|
|
1165
1157
|
}
|
|
1166
1158
|
for (size_t i = 0, L = l->length(); i < L; ++i) {
|
|
1167
|
-
if (eq(l->value_at_index(i), v, ctx)) return new (ctx.mem) Number(
|
|
1159
|
+
if (eq(l->value_at_index(i), v, ctx)) return new (ctx.mem) Number(pstate, i+1);
|
|
1168
1160
|
}
|
|
1169
|
-
return new (ctx.mem) Null(
|
|
1161
|
+
return new (ctx.mem) Null(pstate);
|
|
1170
1162
|
}
|
|
1171
1163
|
|
|
1172
1164
|
Signature join_sig = "join($list1, $list2, $separator: auto)";
|
|
@@ -1177,20 +1169,20 @@ namespace Sass {
|
|
|
1177
1169
|
String_Constant* sep = ARG("$separator", String_Constant);
|
|
1178
1170
|
List::Separator sep_val = (l1 ? l1->separator() : List::SPACE);
|
|
1179
1171
|
if (!l1) {
|
|
1180
|
-
l1 = new (ctx.mem) List(
|
|
1172
|
+
l1 = new (ctx.mem) List(pstate, 1);
|
|
1181
1173
|
*l1 << ARG("$list1", Expression);
|
|
1182
1174
|
sep_val = (l2 ? l2->separator() : List::SPACE);
|
|
1183
1175
|
}
|
|
1184
1176
|
if (!l2) {
|
|
1185
|
-
l2 = new (ctx.mem) List(
|
|
1177
|
+
l2 = new (ctx.mem) List(pstate, 1);
|
|
1186
1178
|
*l2 << ARG("$list2", Expression);
|
|
1187
1179
|
}
|
|
1188
1180
|
size_t len = l1->length() + l2->length();
|
|
1189
1181
|
string sep_str = unquote(sep->value());
|
|
1190
1182
|
if (sep_str == "space") sep_val = List::SPACE;
|
|
1191
1183
|
else if (sep_str == "comma") sep_val = List::COMMA;
|
|
1192
|
-
else if (sep_str != "auto") error("argument `$separator` of `" + string(sig) + "` must be `space`, `comma`, or `auto`",
|
|
1193
|
-
List* result = new (ctx.mem) List(
|
|
1184
|
+
else if (sep_str != "auto") error("argument `$separator` of `" + string(sig) + "` must be `space`, `comma`, or `auto`", pstate);
|
|
1185
|
+
List* result = new (ctx.mem) List(pstate, len, sep_val);
|
|
1194
1186
|
*result += l1;
|
|
1195
1187
|
*result += l2;
|
|
1196
1188
|
return result;
|
|
@@ -1203,14 +1195,14 @@ namespace Sass {
|
|
|
1203
1195
|
Expression* v = ARG("$val", Expression);
|
|
1204
1196
|
String_Constant* sep = ARG("$separator", String_Constant);
|
|
1205
1197
|
if (!l) {
|
|
1206
|
-
l = new (ctx.mem) List(
|
|
1198
|
+
l = new (ctx.mem) List(pstate, 1);
|
|
1207
1199
|
*l << ARG("$list", Expression);
|
|
1208
1200
|
}
|
|
1209
|
-
List* result = new (ctx.mem) List(
|
|
1201
|
+
List* result = new (ctx.mem) List(pstate, l->length() + 1, l->separator());
|
|
1210
1202
|
string sep_str(unquote(sep->value()));
|
|
1211
1203
|
if (sep_str == "space") result->separator(List::SPACE);
|
|
1212
1204
|
else if (sep_str == "comma") result->separator(List::COMMA);
|
|
1213
|
-
else if (sep_str != "auto") error("argument `$separator` of `" + string(sig) + "` must be `space`, `comma`, or `auto`",
|
|
1205
|
+
else if (sep_str != "auto") error("argument `$separator` of `" + string(sig) + "` must be `space`, `comma`, or `auto`", pstate);
|
|
1214
1206
|
*result += l;
|
|
1215
1207
|
*result << v;
|
|
1216
1208
|
return result;
|
|
@@ -1224,7 +1216,7 @@ namespace Sass {
|
|
|
1224
1216
|
for (size_t i = 0, L = arglist->length(); i < L; ++i) {
|
|
1225
1217
|
List* ith = dynamic_cast<List*>(arglist->value_at_index(i));
|
|
1226
1218
|
if (!ith) {
|
|
1227
|
-
ith = new (ctx.mem) List(
|
|
1219
|
+
ith = new (ctx.mem) List(pstate, 1);
|
|
1228
1220
|
*ith << arglist->value_at_index(i);
|
|
1229
1221
|
if (arglist->is_arglist()) {
|
|
1230
1222
|
((Argument*)(*arglist)[i])->value(ith);
|
|
@@ -1234,10 +1226,10 @@ namespace Sass {
|
|
|
1234
1226
|
}
|
|
1235
1227
|
shortest = (i ? std::min(shortest, ith->length()) : ith->length());
|
|
1236
1228
|
}
|
|
1237
|
-
List* zippers = new (ctx.mem) List(
|
|
1229
|
+
List* zippers = new (ctx.mem) List(pstate, shortest, List::COMMA);
|
|
1238
1230
|
size_t L = arglist->length();
|
|
1239
1231
|
for (size_t i = 0; i < shortest; ++i) {
|
|
1240
|
-
List* zipper = new (ctx.mem) List(
|
|
1232
|
+
List* zipper = new (ctx.mem) List(pstate, L);
|
|
1241
1233
|
for (size_t j = 0; j < L; ++j) {
|
|
1242
1234
|
*zipper << (*static_cast<List*>(arglist->value_at_index(j)))[i];
|
|
1243
1235
|
}
|
|
@@ -1249,25 +1241,8 @@ namespace Sass {
|
|
|
1249
1241
|
Signature compact_sig = "compact($values...)";
|
|
1250
1242
|
BUILT_IN(compact)
|
|
1251
1243
|
{
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
if (arglist->length() == 1) {
|
|
1255
|
-
Expression* the_arg = arglist->value_at_index(0);
|
|
1256
|
-
arglist = dynamic_cast<List*>(the_arg);
|
|
1257
|
-
if (!arglist) {
|
|
1258
|
-
List* result = new (ctx.mem) List(path, position, 1, List::COMMA);
|
|
1259
|
-
*result << the_arg;
|
|
1260
|
-
return result;
|
|
1261
|
-
}
|
|
1262
|
-
sep = arglist->separator();
|
|
1263
|
-
}
|
|
1264
|
-
List* result = new (ctx.mem) List(path, position, 0, sep);
|
|
1265
|
-
for (size_t i = 0, L = arglist->length(); i < L; ++i) {
|
|
1266
|
-
Boolean* ith = dynamic_cast<Boolean*>(arglist->value_at_index(i));
|
|
1267
|
-
if (ith && ith->value() == false) continue;
|
|
1268
|
-
*result << arglist->value_at_index(i);
|
|
1269
|
-
}
|
|
1270
|
-
return result;
|
|
1244
|
+
error("`compact` has been removed from libsass because it's not part of the Sass spec", pstate);
|
|
1245
|
+
return 0; // suppress warning, error will exit anyway
|
|
1271
1246
|
}
|
|
1272
1247
|
|
|
1273
1248
|
Signature list_separator_sig = "list_separator($list)";
|
|
@@ -1275,11 +1250,10 @@ namespace Sass {
|
|
|
1275
1250
|
{
|
|
1276
1251
|
List* l = dynamic_cast<List*>(env["$list"]);
|
|
1277
1252
|
if (!l) {
|
|
1278
|
-
l = new (ctx.mem) List(
|
|
1253
|
+
l = new (ctx.mem) List(pstate, 1);
|
|
1279
1254
|
*l << ARG("$list", Expression);
|
|
1280
1255
|
}
|
|
1281
|
-
return new (ctx.mem) String_Constant(
|
|
1282
|
-
position,
|
|
1256
|
+
return new (ctx.mem) String_Constant(pstate,
|
|
1283
1257
|
l->separator() == List::COMMA ? "comma" : "space");
|
|
1284
1258
|
}
|
|
1285
1259
|
|
|
@@ -1295,7 +1269,7 @@ namespace Sass {
|
|
|
1295
1269
|
try {
|
|
1296
1270
|
return m->at(v);
|
|
1297
1271
|
} catch (const std::out_of_range&) {
|
|
1298
|
-
return new (ctx.mem) Null(
|
|
1272
|
+
return new (ctx.mem) Null(pstate);
|
|
1299
1273
|
}
|
|
1300
1274
|
catch (...) { throw; }
|
|
1301
1275
|
}
|
|
@@ -1305,14 +1279,14 @@ namespace Sass {
|
|
|
1305
1279
|
{
|
|
1306
1280
|
Map* m = ARGM("$map", Map, ctx);
|
|
1307
1281
|
Expression* v = ARG("$key", Expression);
|
|
1308
|
-
return new (ctx.mem) Boolean(
|
|
1282
|
+
return new (ctx.mem) Boolean(pstate, m->has(v));
|
|
1309
1283
|
}
|
|
1310
1284
|
|
|
1311
1285
|
Signature map_keys_sig = "map-keys($map)";
|
|
1312
1286
|
BUILT_IN(map_keys)
|
|
1313
1287
|
{
|
|
1314
1288
|
Map* m = ARGM("$map", Map, ctx);
|
|
1315
|
-
List* result = new (ctx.mem) List(
|
|
1289
|
+
List* result = new (ctx.mem) List(pstate, m->length(), List::COMMA);
|
|
1316
1290
|
for ( auto key : m->keys()) {
|
|
1317
1291
|
*result << key;
|
|
1318
1292
|
}
|
|
@@ -1323,7 +1297,7 @@ namespace Sass {
|
|
|
1323
1297
|
BUILT_IN(map_values)
|
|
1324
1298
|
{
|
|
1325
1299
|
Map* m = ARGM("$map", Map, ctx);
|
|
1326
|
-
List* result = new (ctx.mem) List(
|
|
1300
|
+
List* result = new (ctx.mem) List(pstate, m->length(), List::COMMA);
|
|
1327
1301
|
for ( auto key : m->keys()) {
|
|
1328
1302
|
*result << m->at(key);
|
|
1329
1303
|
}
|
|
@@ -1337,7 +1311,7 @@ namespace Sass {
|
|
|
1337
1311
|
Map* m2 = ARGM("$map2", Map, ctx);
|
|
1338
1312
|
|
|
1339
1313
|
size_t len = m1->length() + m2->length();
|
|
1340
|
-
Map* result = new (ctx.mem) Map(
|
|
1314
|
+
Map* result = new (ctx.mem) Map(pstate, len);
|
|
1341
1315
|
*result += m1;
|
|
1342
1316
|
*result += m2;
|
|
1343
1317
|
return result;
|
|
@@ -1349,7 +1323,7 @@ namespace Sass {
|
|
|
1349
1323
|
bool remove;
|
|
1350
1324
|
Map* m = ARGM("$map", Map, ctx);
|
|
1351
1325
|
List* arglist = ARG("$keys", List);
|
|
1352
|
-
Map* result = new (ctx.mem) Map(
|
|
1326
|
+
Map* result = new (ctx.mem) Map(pstate, 1);
|
|
1353
1327
|
for (auto key : m->keys()) {
|
|
1354
1328
|
remove = false;
|
|
1355
1329
|
for (size_t j = 0, K = arglist->length(); j < K && !remove; ++j) {
|
|
@@ -1364,14 +1338,14 @@ namespace Sass {
|
|
|
1364
1338
|
BUILT_IN(keywords)
|
|
1365
1339
|
{
|
|
1366
1340
|
List* arglist = new (ctx.mem) List(*ARG("$args", List));
|
|
1367
|
-
Map* result = new (ctx.mem) Map(
|
|
1341
|
+
Map* result = new (ctx.mem) Map(pstate, 1);
|
|
1368
1342
|
// The parser ensures the ordering of arguments so we can assert this
|
|
1369
1343
|
// isn't keyword argument list the first argument isn't a keyword argument
|
|
1370
1344
|
if (!(arglist->empty() || ((Argument*)(*arglist)[0])->is_keyword_argument())) return result;
|
|
1371
1345
|
for (size_t i = 0, L = arglist->length(); i < L; ++i) {
|
|
1372
1346
|
string name = string(((Argument*)(*arglist)[i])->name());
|
|
1373
1347
|
string sanitized_name = string(name, 1);
|
|
1374
|
-
*result << make_pair(new (ctx.mem) String_Constant(
|
|
1348
|
+
*result << make_pair(new (ctx.mem) String_Constant(pstate, sanitized_name),
|
|
1375
1349
|
((Argument*)(*arglist)[i])->value());
|
|
1376
1350
|
}
|
|
1377
1351
|
return result;
|
|
@@ -1386,22 +1360,22 @@ namespace Sass {
|
|
|
1386
1360
|
{
|
|
1387
1361
|
Expression* v = ARG("$value", Expression);
|
|
1388
1362
|
if (v->concrete_type() == Expression::STRING) {
|
|
1389
|
-
To_String to_string;
|
|
1363
|
+
To_String to_string(&ctx);
|
|
1390
1364
|
string str(v->perform(&to_string));
|
|
1391
1365
|
if (ctx.names_to_colors.count(str)) {
|
|
1392
|
-
return new (ctx.mem) String_Constant(
|
|
1366
|
+
return new (ctx.mem) String_Constant(pstate, "color");
|
|
1393
1367
|
}
|
|
1394
1368
|
}
|
|
1395
|
-
return new (ctx.mem) String_Constant(
|
|
1369
|
+
return new (ctx.mem) String_Constant(pstate, ARG("$value", Expression)->type());
|
|
1396
1370
|
}
|
|
1397
1371
|
|
|
1398
1372
|
Signature unit_sig = "unit($number)";
|
|
1399
1373
|
BUILT_IN(unit)
|
|
1400
|
-
{ return new (ctx.mem)
|
|
1374
|
+
{ return new (ctx.mem) String_Quoted(pstate, quote(ARG("$number", Number)->unit(), '"')); }
|
|
1401
1375
|
|
|
1402
1376
|
Signature unitless_sig = "unitless($number)";
|
|
1403
1377
|
BUILT_IN(unitless)
|
|
1404
|
-
{ return new (ctx.mem) Boolean(
|
|
1378
|
+
{ return new (ctx.mem) Boolean(pstate, ARG("$number", Number)->is_unitless()); }
|
|
1405
1379
|
|
|
1406
1380
|
Signature comparable_sig = "comparable($number-1, $number-2)";
|
|
1407
1381
|
BUILT_IN(comparable)
|
|
@@ -1409,62 +1383,62 @@ namespace Sass {
|
|
|
1409
1383
|
Number* n1 = ARG("$number-1", Number);
|
|
1410
1384
|
Number* n2 = ARG("$number-2", Number);
|
|
1411
1385
|
if (n1->is_unitless() || n2->is_unitless()) {
|
|
1412
|
-
return new (ctx.mem) Boolean(
|
|
1386
|
+
return new (ctx.mem) Boolean(pstate, true);
|
|
1413
1387
|
}
|
|
1414
1388
|
Number tmp_n2(*n2);
|
|
1415
1389
|
tmp_n2.normalize(n1->find_convertible_unit());
|
|
1416
|
-
return new (ctx.mem) Boolean(
|
|
1390
|
+
return new (ctx.mem) Boolean(pstate, n1->unit() == tmp_n2.unit());
|
|
1417
1391
|
}
|
|
1418
1392
|
|
|
1419
1393
|
Signature variable_exists_sig = "variable-exists($name)";
|
|
1420
1394
|
BUILT_IN(variable_exists)
|
|
1421
1395
|
{
|
|
1422
|
-
string s = unquote(ARG("$name", String_Constant)->value());
|
|
1396
|
+
string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
|
|
1423
1397
|
|
|
1424
1398
|
if(d_env.has("$"+s)) {
|
|
1425
|
-
return new (ctx.mem) Boolean(
|
|
1399
|
+
return new (ctx.mem) Boolean(pstate, true);
|
|
1426
1400
|
}
|
|
1427
1401
|
else {
|
|
1428
|
-
return new (ctx.mem) Boolean(
|
|
1402
|
+
return new (ctx.mem) Boolean(pstate, false);
|
|
1429
1403
|
}
|
|
1430
1404
|
}
|
|
1431
1405
|
|
|
1432
1406
|
Signature global_variable_exists_sig = "global-variable-exists($name)";
|
|
1433
1407
|
BUILT_IN(global_variable_exists)
|
|
1434
1408
|
{
|
|
1435
|
-
string s = unquote(ARG("$name", String_Constant)->value());
|
|
1409
|
+
string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
|
|
1436
1410
|
|
|
1437
1411
|
if(d_env.global_frame_has("$"+s)) {
|
|
1438
|
-
return new (ctx.mem) Boolean(
|
|
1412
|
+
return new (ctx.mem) Boolean(pstate, true);
|
|
1439
1413
|
}
|
|
1440
1414
|
else {
|
|
1441
|
-
return new (ctx.mem) Boolean(
|
|
1415
|
+
return new (ctx.mem) Boolean(pstate, false);
|
|
1442
1416
|
}
|
|
1443
1417
|
}
|
|
1444
1418
|
|
|
1445
1419
|
Signature function_exists_sig = "function-exists($name)";
|
|
1446
1420
|
BUILT_IN(function_exists)
|
|
1447
1421
|
{
|
|
1448
|
-
string s = unquote(ARG("$name", String_Constant)->value());
|
|
1422
|
+
string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
|
|
1449
1423
|
|
|
1450
1424
|
if(d_env.global_frame_has(s+"[f]")) {
|
|
1451
|
-
return new (ctx.mem) Boolean(
|
|
1425
|
+
return new (ctx.mem) Boolean(pstate, true);
|
|
1452
1426
|
}
|
|
1453
1427
|
else {
|
|
1454
|
-
return new (ctx.mem) Boolean(
|
|
1428
|
+
return new (ctx.mem) Boolean(pstate, false);
|
|
1455
1429
|
}
|
|
1456
1430
|
}
|
|
1457
1431
|
|
|
1458
1432
|
Signature mixin_exists_sig = "mixin-exists($name)";
|
|
1459
1433
|
BUILT_IN(mixin_exists)
|
|
1460
1434
|
{
|
|
1461
|
-
string s = unquote(ARG("$name", String_Constant)->value());
|
|
1435
|
+
string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
|
|
1462
1436
|
|
|
1463
1437
|
if(d_env.global_frame_has(s+"[m]")) {
|
|
1464
|
-
return new (ctx.mem) Boolean(
|
|
1438
|
+
return new (ctx.mem) Boolean(pstate, true);
|
|
1465
1439
|
}
|
|
1466
1440
|
else {
|
|
1467
|
-
return new (ctx.mem) Boolean(
|
|
1441
|
+
return new (ctx.mem) Boolean(pstate, false);
|
|
1468
1442
|
}
|
|
1469
1443
|
}
|
|
1470
1444
|
|
|
@@ -1474,25 +1448,25 @@ namespace Sass {
|
|
|
1474
1448
|
string s = unquote(ARG("$name", String_Constant)->value());
|
|
1475
1449
|
|
|
1476
1450
|
if(features.find(s) == features.end()) {
|
|
1477
|
-
return new (ctx.mem) Boolean(
|
|
1451
|
+
return new (ctx.mem) Boolean(pstate, false);
|
|
1478
1452
|
}
|
|
1479
1453
|
else {
|
|
1480
|
-
return new (ctx.mem) Boolean(
|
|
1454
|
+
return new (ctx.mem) Boolean(pstate, true);
|
|
1481
1455
|
}
|
|
1482
1456
|
}
|
|
1483
1457
|
|
|
1484
1458
|
Signature call_sig = "call($name, $args...)";
|
|
1485
1459
|
BUILT_IN(call)
|
|
1486
1460
|
{
|
|
1487
|
-
string name = unquote(ARG("$name", String_Constant)->value());
|
|
1461
|
+
string name = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
|
|
1488
1462
|
List* arglist = new (ctx.mem) List(*ARG("$args", List));
|
|
1489
1463
|
|
|
1490
|
-
Arguments* args = new (ctx.mem) Arguments(
|
|
1464
|
+
Arguments* args = new (ctx.mem) Arguments(pstate);
|
|
1491
1465
|
for (size_t i = 0, L = arglist->length(); i < L; ++i) {
|
|
1492
|
-
Argument* arg = new (ctx.mem) Argument(
|
|
1466
|
+
Argument* arg = new (ctx.mem) Argument(pstate, arglist->value_at_index(i));
|
|
1493
1467
|
*args << arg;
|
|
1494
1468
|
}
|
|
1495
|
-
Function_Call* func = new (ctx.mem) Function_Call(
|
|
1469
|
+
Function_Call* func = new (ctx.mem) Function_Call(pstate, name, args);
|
|
1496
1470
|
Eval eval(ctx, &d_env, backtrace);
|
|
1497
1471
|
return func->perform(&eval);
|
|
1498
1472
|
|
|
@@ -1504,7 +1478,7 @@ namespace Sass {
|
|
|
1504
1478
|
|
|
1505
1479
|
Signature not_sig = "not($value)";
|
|
1506
1480
|
BUILT_IN(sass_not)
|
|
1507
|
-
{ return new (ctx.mem) Boolean(
|
|
1481
|
+
{ return new (ctx.mem) Boolean(pstate, ARG("$value", Expression)->is_false()); }
|
|
1508
1482
|
|
|
1509
1483
|
Signature if_sig = "if($condition, $if-true, $if-false)";
|
|
1510
1484
|
// BUILT_IN(sass_if)
|
|
@@ -1528,11 +1502,8 @@ namespace Sass {
|
|
|
1528
1502
|
Signature image_url_sig = "image-url($path, $only-path: false, $cache-buster: false)";
|
|
1529
1503
|
BUILT_IN(image_url)
|
|
1530
1504
|
{
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
string full_path(quote(ctx.image_path + "/" + unquote(ipath->value()), '"'));
|
|
1534
|
-
if (!only_path) full_path = "url(" + full_path + ")";
|
|
1535
|
-
return new (ctx.mem) String_Constant(path, position, full_path);
|
|
1505
|
+
error("`image_url` has been removed from libsass because it's not part of the Sass spec", pstate);
|
|
1506
|
+
return 0; // suppress warning, error will exit anyway
|
|
1536
1507
|
}
|
|
1537
1508
|
|
|
1538
1509
|
//////////////////////////
|
|
@@ -1544,11 +1515,23 @@ namespace Sass {
|
|
|
1544
1515
|
{
|
|
1545
1516
|
Expression* v = ARG("$value", Expression);
|
|
1546
1517
|
if (v->concrete_type() == Expression::NULL_VAL) {
|
|
1547
|
-
return new (ctx.mem) String_Constant(
|
|
1518
|
+
return new (ctx.mem) String_Constant(pstate, "null");
|
|
1548
1519
|
} else if (v->concrete_type() == Expression::BOOLEAN && *v == 0) {
|
|
1549
|
-
return new (ctx.mem) String_Constant(
|
|
1520
|
+
return new (ctx.mem) String_Constant(pstate, "false");
|
|
1521
|
+
} else if (v->concrete_type() == Expression::STRING) {
|
|
1522
|
+
return v;
|
|
1523
|
+
} else {
|
|
1524
|
+
Output_Style old_style;
|
|
1525
|
+
old_style = ctx.output_style;
|
|
1526
|
+
ctx.output_style = NESTED;
|
|
1527
|
+
To_String to_string(&ctx);
|
|
1528
|
+
string inspect = v->perform(&to_string);
|
|
1529
|
+
ctx.output_style = old_style;
|
|
1530
|
+
return new (ctx.mem) String_Constant(pstate, inspect);
|
|
1531
|
+
|
|
1532
|
+
|
|
1550
1533
|
}
|
|
1551
|
-
return v;
|
|
1534
|
+
// return v;
|
|
1552
1535
|
}
|
|
1553
1536
|
|
|
1554
1537
|
Signature unique_id_sig = "unique-id()";
|
|
@@ -1556,9 +1539,9 @@ namespace Sass {
|
|
|
1556
1539
|
{
|
|
1557
1540
|
std::stringstream ss;
|
|
1558
1541
|
uniform_real_distribution<> distributor(0, 4294967296); // 16^8
|
|
1559
|
-
uint_fast32_t distributed = distributor(rand);
|
|
1542
|
+
uint_fast32_t distributed = static_cast<uint_fast32_t>(distributor(rand));
|
|
1560
1543
|
ss << "u" << setfill('0') << setw(8) << std::hex << distributed;
|
|
1561
|
-
return new (ctx.mem) String_Constant(
|
|
1544
|
+
return new (ctx.mem) String_Constant(pstate, ss.str());
|
|
1562
1545
|
}
|
|
1563
1546
|
|
|
1564
1547
|
}
|