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.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -1
  3. data/ext/libsass/.gitignore +13 -6
  4. data/ext/libsass/Makefile +42 -26
  5. data/ext/libsass/Makefile.am +43 -30
  6. data/ext/libsass/Readme.md +4 -2
  7. data/ext/libsass/appveyor.yml +10 -14
  8. data/ext/libsass/ast.cpp +54 -44
  9. data/ext/libsass/ast.hpp +404 -236
  10. data/ext/libsass/ast_def_macros.hpp +5 -0
  11. data/ext/libsass/ast_factory.hpp +6 -3
  12. data/ext/libsass/ast_fwd_decl.hpp +12 -0
  13. data/ext/libsass/b64/encode.h +2 -2
  14. data/ext/libsass/backtrace.hpp +13 -17
  15. data/ext/libsass/base64vlq.hpp +4 -1
  16. data/ext/libsass/bind.cpp +12 -15
  17. data/ext/libsass/bind.hpp +6 -6
  18. data/ext/libsass/color_names.hpp +4 -1
  19. data/ext/libsass/configure.ac +7 -21
  20. data/ext/libsass/constants.cpp +6 -4
  21. data/ext/libsass/constants.hpp +10 -4
  22. data/ext/libsass/context.cpp +89 -58
  23. data/ext/libsass/context.hpp +28 -35
  24. data/ext/libsass/contextualize.cpp +20 -10
  25. data/ext/libsass/contextualize.hpp +8 -23
  26. data/ext/libsass/contrib/libsass.spec +66 -0
  27. data/ext/libsass/cssize.cpp +547 -0
  28. data/ext/libsass/cssize.hpp +82 -0
  29. data/ext/libsass/debug.hpp +3 -3
  30. data/ext/libsass/debugger.hpp +358 -0
  31. data/ext/libsass/emitter.cpp +255 -0
  32. data/ext/libsass/emitter.hpp +83 -0
  33. data/ext/libsass/environment.hpp +7 -3
  34. data/ext/libsass/error_handling.cpp +11 -14
  35. data/ext/libsass/error_handling.hpp +9 -7
  36. data/ext/libsass/eval.cpp +253 -161
  37. data/ext/libsass/eval.hpp +13 -13
  38. data/ext/libsass/expand.cpp +135 -64
  39. data/ext/libsass/expand.hpp +11 -13
  40. data/ext/libsass/extend.cpp +66 -20
  41. data/ext/libsass/extend.hpp +6 -11
  42. data/ext/libsass/file.cpp +31 -26
  43. data/ext/libsass/file.hpp +6 -1
  44. data/ext/libsass/functions.cpp +270 -287
  45. data/ext/libsass/functions.hpp +8 -11
  46. data/ext/libsass/inspect.cpp +385 -255
  47. data/ext/libsass/inspect.hpp +15 -26
  48. data/ext/libsass/kwd_arg_macros.hpp +5 -0
  49. data/ext/libsass/mapping.hpp +4 -3
  50. data/ext/libsass/memory_manager.hpp +5 -2
  51. data/ext/libsass/node.cpp +50 -50
  52. data/ext/libsass/node.hpp +26 -27
  53. data/ext/libsass/operation.hpp +15 -4
  54. data/ext/libsass/output.cpp +401 -0
  55. data/ext/libsass/output.hpp +56 -0
  56. data/ext/libsass/parser.cpp +573 -399
  57. data/ext/libsass/parser.hpp +122 -88
  58. data/ext/libsass/paths.hpp +7 -2
  59. data/ext/libsass/plugins.cpp +155 -0
  60. data/ext/libsass/plugins.hpp +56 -0
  61. data/ext/libsass/position.cpp +128 -0
  62. data/ext/libsass/position.hpp +108 -11
  63. data/ext/libsass/prelexer.cpp +184 -110
  64. data/ext/libsass/prelexer.hpp +131 -24
  65. data/ext/libsass/remove_placeholders.cpp +1 -1
  66. data/ext/libsass/remove_placeholders.hpp +6 -6
  67. data/ext/libsass/sass.cpp +3 -3
  68. data/ext/libsass/sass.h +12 -4
  69. data/ext/libsass/sass2scss.cpp +3 -2
  70. data/ext/libsass/sass2scss.h +5 -0
  71. data/ext/libsass/sass_context.cpp +136 -37
  72. data/ext/libsass/sass_context.h +19 -10
  73. data/ext/libsass/sass_functions.cpp +29 -2
  74. data/ext/libsass/sass_functions.h +8 -2
  75. data/ext/libsass/sass_interface.cpp +32 -23
  76. data/ext/libsass/sass_interface.h +9 -4
  77. data/ext/libsass/sass_util.cpp +19 -23
  78. data/ext/libsass/sass_util.hpp +28 -27
  79. data/ext/libsass/sass_values.cpp +6 -4
  80. data/ext/libsass/sass_values.h +3 -3
  81. data/ext/libsass/script/ci-build-libsass +13 -1
  82. data/ext/libsass/script/ci-report-coverage +2 -1
  83. data/ext/libsass/source_map.cpp +79 -28
  84. data/ext/libsass/source_map.hpp +35 -16
  85. data/ext/libsass/subset_map.hpp +6 -4
  86. data/ext/libsass/to_c.hpp +4 -4
  87. data/ext/libsass/to_string.cpp +13 -8
  88. data/ext/libsass/to_string.hpp +6 -4
  89. data/ext/libsass/units.cpp +2 -1
  90. data/ext/libsass/units.hpp +6 -1
  91. data/ext/libsass/utf8_string.cpp +0 -5
  92. data/ext/libsass/utf8_string.hpp +3 -2
  93. data/ext/libsass/util.cpp +461 -49
  94. data/ext/libsass/util.hpp +34 -13
  95. data/ext/libsass/version.sh +10 -0
  96. data/ext/libsass/win/libsass.filters +20 -11
  97. data/ext/libsass/win/libsass.vcxproj +11 -8
  98. data/lib/sassc/importer.rb +1 -8
  99. data/lib/sassc/native.rb +7 -0
  100. data/lib/sassc/native/native_context_api.rb +5 -5
  101. data/lib/sassc/version.rb +1 -1
  102. data/test/native_test.rb +1 -1
  103. metadata +14 -10
  104. data/ext/libsass/copy_c_str.cpp +0 -13
  105. data/ext/libsass/copy_c_str.hpp +0 -5
  106. data/ext/libsass/output_compressed.cpp +0 -401
  107. data/ext/libsass/output_compressed.hpp +0 -95
  108. data/ext/libsass/output_nested.cpp +0 -364
  109. data/ext/libsass/output_nested.hpp +0 -108
  110. data/ext/libsass/test-driver +0 -127
  111. data/ext/libsass/token.hpp +0 -32
@@ -28,10 +28,13 @@ namespace Sass {
28
28
 
29
29
  Selector* Contextualize::operator()(Selector_Schema* s)
30
30
  {
31
- To_String to_string;
31
+ To_String to_string(&ctx);
32
32
  string result_str(s->contents()->perform(eval->with(env, backtrace))->perform(&to_string));
33
33
  result_str += '{'; // the parser looks for a brace to end the selector
34
- Selector* result_sel = Parser::from_c_str(result_str.c_str(), ctx, s->path(), s->position()).parse_selector_group();
34
+ Parser p = Parser::from_c_str(result_str.c_str(), ctx, s->pstate());
35
+ p.block_stack.push_back(s->last_block());
36
+ p.last_media_block = s->media_block();
37
+ Selector* result_sel = p.parse_selector_group();
35
38
  return result_sel->perform(this);
36
39
  }
37
40
 
@@ -40,17 +43,18 @@ namespace Sass {
40
43
  Selector_List* p = static_cast<Selector_List*>(parent);
41
44
  Selector_List* ss = 0;
42
45
  if (p) {
43
- ss = new (ctx.mem) Selector_List(s->path(), s->position(), p->length() * s->length());
46
+ ss = new (ctx.mem) Selector_List(s->pstate(), p->length() * s->length());
44
47
  for (size_t i = 0, L = p->length(); i < L; ++i) {
45
48
  for (size_t j = 0, L = s->length(); j < L; ++j) {
46
49
  parent = (*p)[i];
47
50
  Complex_Selector* comb = static_cast<Complex_Selector*>((*s)[j]->perform(this));
51
+ if (parent->has_line_feed()) comb->has_line_feed(true);
48
52
  if (comb) *ss << comb;
49
53
  }
50
54
  }
51
55
  }
52
56
  else {
53
- ss = new (ctx.mem) Selector_List(s->path(), s->position(), s->length());
57
+ ss = new (ctx.mem) Selector_List(s->pstate(), s->length());
54
58
  for (size_t j = 0, L = s->length(); j < L; ++j) {
55
59
  Complex_Selector* comb = static_cast<Complex_Selector*>((*s)[j]->perform(this));
56
60
  if (comb) *ss << comb;
@@ -61,8 +65,10 @@ namespace Sass {
61
65
 
62
66
  Selector* Contextualize::operator()(Complex_Selector* s)
63
67
  {
64
- To_String to_string;
68
+ To_String to_string(&ctx);
65
69
  Complex_Selector* ss = new (ctx.mem) Complex_Selector(*s);
70
+ // ss->last_block(s->last_block());
71
+ // ss->media_block(s->media_block());
66
72
  Compound_Selector* new_head = 0;
67
73
  Complex_Selector* new_tail = 0;
68
74
  if (ss->head()) {
@@ -71,6 +77,8 @@ namespace Sass {
71
77
  }
72
78
  if (ss->tail()) {
73
79
  new_tail = static_cast<Complex_Selector*>(s->tail()->perform(this));
80
+ // new_tail->last_block(s->last_block());
81
+ // new_tail->media_block(s->media_block());
74
82
  ss->tail(new_tail);
75
83
  }
76
84
  if ((new_head && new_head->has_placeholder()) || (new_tail && new_tail->has_placeholder())) {
@@ -89,11 +97,14 @@ namespace Sass {
89
97
 
90
98
  Selector* Contextualize::operator()(Compound_Selector* s)
91
99
  {
92
- To_String to_string;
100
+ To_String to_string(&ctx);
93
101
  if (placeholder && extender && s->perform(&to_string) == placeholder->perform(&to_string)) {
94
102
  return extender;
95
103
  }
96
- Compound_Selector* ss = new (ctx.mem) Compound_Selector(s->path(), s->position(), s->length());
104
+ Compound_Selector* ss = new (ctx.mem) Compound_Selector(s->pstate(), s->length());
105
+ ss->last_block(s->last_block());
106
+ ss->media_block(s->media_block());
107
+ ss->has_line_break(s->has_line_break());
97
108
  for (size_t i = 0, L = s->length(); i < L; ++i) {
98
109
  Simple_Selector* simp = static_cast<Simple_Selector*>((*s)[i]->perform(this));
99
110
  if (simp) *ss << simp;
@@ -105,8 +116,7 @@ namespace Sass {
105
116
  {
106
117
  Selector* old_parent = parent;
107
118
  parent = 0;
108
- Wrapped_Selector* neg = new (ctx.mem) Wrapped_Selector(s->path(),
109
- s->position(),
119
+ Wrapped_Selector* neg = new (ctx.mem) Wrapped_Selector(s->pstate(),
110
120
  s->name(),
111
121
  s->selector()->perform(this));
112
122
  parent = old_parent;
@@ -136,7 +146,7 @@ namespace Sass {
136
146
 
137
147
  Selector* Contextualize::operator()(Selector_Placeholder* p)
138
148
  {
139
- To_String to_string;
149
+ To_String to_string(&ctx);
140
150
  if (placeholder && extender && p->perform(&to_string) == placeholder->perform(&to_string)) {
141
151
  return extender;
142
152
  }
@@ -1,30 +1,13 @@
1
- #define SASS_CONTEXTUALIZE
1
+ #ifndef SASS_CONTEXTUALIZE_H
2
+ #define SASS_CONTEXTUALIZE_H
2
3
 
3
- #ifndef SASS_ENVIRONMENT
4
- #include "environment.hpp"
5
- #endif
6
-
7
- #ifndef SASS_OPERATION
4
+ #include "eval.hpp"
5
+ #include "context.hpp"
8
6
  #include "operation.hpp"
9
- #endif
7
+ #include "environment.hpp"
8
+ #include "ast_fwd_decl.hpp"
10
9
 
11
10
  namespace Sass {
12
- class AST_Node;
13
- class Selector;
14
- class Selector_Schema;
15
- class Selector_List;
16
- class Complex_Selector;
17
- class Compound_Selector;
18
- class Wrapped_Selector;
19
- class Pseudo_Selector;
20
- class Attribute_Selector;
21
- class Selector_Qualifier;
22
- class Type_Selector;
23
- class Selector_Placeholder;
24
- class Selector_Reference;
25
- class Simple_Selector;
26
- struct Context;
27
- class Eval;
28
11
  struct Backtrace;
29
12
 
30
13
  typedef Environment<AST_Node*> Env;
@@ -63,3 +46,5 @@ namespace Sass {
63
46
  Selector* fallback(U x) { return fallback_impl(x); }
64
47
  };
65
48
  }
49
+
50
+ #endif
@@ -0,0 +1,66 @@
1
+ Name: libsass
2
+ Version: %{version}
3
+ Release: 1%{?dist}
4
+ Summary: A C/C++ implementation of a Sass compiler
5
+
6
+ License: MIT
7
+ URL: http://libsass.org
8
+ Source0: %{name}-%{version}.tar.gz
9
+
10
+ BuildRequires: gcc-c++ >= 4.7
11
+ BuildRequires: autoconf
12
+ BuildRequires: automake
13
+ BuildRequires: libtool
14
+
15
+
16
+ %description
17
+ LibSass is a C/C++ port of the Sass engine. The point is to be simple, fast, and easy to integrate.
18
+
19
+ %package devel
20
+ Summary: Development files for %{name}
21
+ Requires: %{name}%{?_isa} = %{version}-%{release}
22
+
23
+
24
+ %description devel
25
+ The %{name}-devel package contains libraries and header files for
26
+ developing applications that use %{name}.
27
+
28
+
29
+ %prep
30
+ %setup -q
31
+ autoreconf --force --install
32
+
33
+
34
+ %build
35
+ %configure --disable-static \
36
+ --disable-tests \
37
+ --enable-shared
38
+
39
+ make %{?_smp_mflags}
40
+
41
+
42
+ %install
43
+ %make_install
44
+ find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';'
45
+
46
+
47
+ %post -p /sbin/ldconfig
48
+
49
+ %postun -p /sbin/ldconfig
50
+
51
+
52
+ %files
53
+ %doc Readme.md LICENSE
54
+ %{_libdir}/*.so.*
55
+
56
+ %files devel
57
+ %doc
58
+ %{_includedir}/*
59
+ %{_libdir}/*.so
60
+ %{_libdir}/pkgconfig/*.pc
61
+
62
+
63
+ %changelog
64
+ * Tue Feb 10 2015 Gawain Lynch <gawain.lynch@gmail.com> - 3.1.0-1
65
+ - Initial SPEC file
66
+
@@ -0,0 +1,547 @@
1
+ #include <iostream>
2
+ #include <typeinfo>
3
+
4
+ #include "cssize.hpp"
5
+ #include "to_string.hpp"
6
+ #include "context.hpp"
7
+ #include "backtrace.hpp"
8
+
9
+ namespace Sass {
10
+
11
+ Cssize::Cssize(Context& ctx, Env* env, Backtrace* bt)
12
+ : ctx(ctx),
13
+ env(env),
14
+ block_stack(vector<Block*>()),
15
+ p_stack(vector<Statement*>()),
16
+ backtrace(bt)
17
+ { }
18
+
19
+ Statement* Cssize::parent()
20
+ {
21
+ return p_stack.size() ? p_stack.back() : block_stack.front();
22
+ }
23
+
24
+ Statement* Cssize::operator()(Block* b)
25
+ {
26
+ Env new_env;
27
+ new_env.link(*env);
28
+ env = &new_env;
29
+ Block* bb = new (ctx.mem) Block(b->pstate(), b->length(), b->is_root());
30
+ // bb->tabs(b->tabs());
31
+ block_stack.push_back(bb);
32
+ append_block(b);
33
+ block_stack.pop_back();
34
+ env = env->parent();
35
+ return bb;
36
+ }
37
+
38
+ Statement* Cssize::operator()(At_Rule* r)
39
+ {
40
+ if (!r->block() || !r->block()->length()) return r;
41
+
42
+ if (parent()->statement_type() == Statement::RULESET)
43
+ {
44
+ return (r->is_keyframes()) ? new (ctx.mem) Bubble(r->pstate(), r) : bubble(r);
45
+ }
46
+
47
+ p_stack.push_back(r);
48
+ At_Rule* rr = new (ctx.mem) At_Rule(r->pstate(),
49
+ r->keyword(),
50
+ r->selector(),
51
+ r->block() ? r->block()->perform(this)->block() : 0);
52
+ if (r->value()) rr->value(r->value());
53
+ p_stack.pop_back();
54
+
55
+ bool directive_exists = false;
56
+ size_t L = rr->block() ? rr->block()->length() : 0;
57
+ for (size_t i = 0; i < L && !directive_exists; ++i) {
58
+ Statement* s = (*r->block())[i];
59
+ if (s->statement_type() != Statement::BUBBLE) directive_exists = true;
60
+ else {
61
+ s = static_cast<Bubble*>(s)->node();
62
+ if (s->statement_type() != Statement::DIRECTIVE) directive_exists = false;
63
+ else directive_exists = (static_cast<At_Rule*>(s)->keyword() == rr->keyword());
64
+ }
65
+
66
+ }
67
+
68
+ Block* result = new (ctx.mem) Block(rr->pstate());
69
+ if (!(directive_exists || rr->is_keyframes()))
70
+ {
71
+ At_Rule* empty_node = static_cast<At_Rule*>(rr);
72
+ empty_node->block(new (ctx.mem) Block(rr->block() ? rr->block()->pstate() : rr->pstate()));
73
+ *result << empty_node;
74
+ }
75
+
76
+ Statement* ss = debubble(rr->block() ? rr->block() : new (ctx.mem) Block(rr->pstate()), rr);
77
+ for (size_t i = 0, L = ss->block()->length(); i < L; ++i) {
78
+ *result << (*ss->block())[i];
79
+ }
80
+
81
+ return result;
82
+ }
83
+
84
+ Statement* Cssize::operator()(Keyframe_Rule* r)
85
+ {
86
+ if (!r->block() || !r->block()->length()) return r;
87
+
88
+ Keyframe_Rule* rr = new (ctx.mem) Keyframe_Rule(r->pstate(),
89
+ r->block()->perform(this)->block());
90
+ if (r->rules()) rr->rules(r->rules());
91
+
92
+ return debubble(rr->block(), rr)->block();
93
+ }
94
+
95
+ Statement* Cssize::operator()(Ruleset* r)
96
+ {
97
+ p_stack.push_back(r);
98
+ Ruleset* rr = new (ctx.mem) Ruleset(r->pstate(),
99
+ r->selector(),
100
+ r->block()->perform(this)->block());
101
+ // rr->tabs(r->block()->tabs());
102
+ p_stack.pop_back();
103
+
104
+ Block* props = new (ctx.mem) Block(rr->block()->pstate());
105
+ Block* rules = new (ctx.mem) Block(rr->block()->pstate());
106
+ for (size_t i = 0, L = rr->block()->length(); i < L; i++)
107
+ {
108
+ Statement* s = (*rr->block())[i];
109
+ if (bubblable(s)) *rules << s;
110
+ if (!bubblable(s)) *props << s;
111
+ }
112
+
113
+ if (props->length())
114
+ {
115
+ Block* bb = new (ctx.mem) Block(rr->block()->pstate());
116
+ *bb += props;
117
+ rr->block(bb);
118
+
119
+ for (size_t i = 0, L = rules->length(); i < L; i++)
120
+ {
121
+ (*rules)[i]->tabs((*rules)[i]->tabs() + 1);
122
+ }
123
+
124
+ rules->unshift(rr);
125
+ }
126
+
127
+ rules = debubble(rules)->block();
128
+
129
+ if (!(!rules->length() ||
130
+ !bubblable(rules->last()) ||
131
+ parent()->statement_type() == Statement::RULESET))
132
+ {
133
+ rules->last()->group_end(true);
134
+ }
135
+
136
+ return rules;
137
+ }
138
+
139
+ Statement* Cssize::operator()(Media_Block* m)
140
+ {
141
+ if (parent()->statement_type() == Statement::RULESET)
142
+ { return bubble(m); }
143
+
144
+ if (parent()->statement_type() == Statement::MEDIA)
145
+ { return new (ctx.mem) Bubble(m->pstate(), m); }
146
+
147
+ p_stack.push_back(m);
148
+
149
+ Media_Block* mm = new (ctx.mem) Media_Block(m->pstate(),
150
+ m->media_queries(),
151
+ m->block()->perform(this)->block());
152
+ mm->tabs(m->tabs());
153
+
154
+ p_stack.pop_back();
155
+
156
+ return debubble(mm->block(), mm)->block();
157
+ }
158
+
159
+ Statement* Cssize::operator()(Feature_Block* m)
160
+ {
161
+ if (!m->block()->length())
162
+ { return m; }
163
+
164
+ if (parent()->statement_type() == Statement::RULESET)
165
+ { return bubble(m); }
166
+
167
+ p_stack.push_back(m);
168
+
169
+ Feature_Block* mm = new (ctx.mem) Feature_Block(m->pstate(),
170
+ m->feature_queries(),
171
+ m->block()->perform(this)->block());
172
+ mm->tabs(m->tabs());
173
+
174
+ p_stack.pop_back();
175
+
176
+ return debubble(mm->block(), mm)->block();
177
+ }
178
+
179
+ Statement* Cssize::operator()(At_Root_Block* m)
180
+ {
181
+ bool tmp = false;
182
+ for (size_t i = 0, L = p_stack.size(); i < L; ++i) {
183
+ Statement* s = p_stack[i];
184
+ tmp |= m->exclude_node(s);
185
+ }
186
+
187
+ if (!tmp)
188
+ {
189
+ Block* bb = m->block()->perform(this)->block();
190
+ for (size_t i = 0, L = bb->length(); i < L; ++i) {
191
+ // (bb->elements())[i]->tabs(m->tabs());
192
+ if (bubblable((*bb)[i])) (*bb)[i]->tabs((*bb)[i]->tabs() + m->tabs());
193
+ }
194
+ if (bb->length() && bubblable(bb->last())) bb->last()->group_end(m->group_end());
195
+ return bb;
196
+ }
197
+
198
+ if (m->exclude_node(parent()))
199
+ {
200
+ return new (ctx.mem) Bubble(m->pstate(), m);
201
+ }
202
+
203
+ return bubble(m);
204
+ }
205
+
206
+ Statement* Cssize::bubble(At_Rule* m)
207
+ {
208
+ Block* bb = new (ctx.mem) Block(this->parent()->pstate());
209
+ Has_Block* new_rule = static_cast<Has_Block*>(shallow_copy(this->parent()));
210
+ new_rule->block(bb);
211
+ new_rule->tabs(this->parent()->tabs());
212
+
213
+ size_t L = m->block() ? m->block()->length() : 0;
214
+ for (size_t i = 0; i < L; ++i) {
215
+ *new_rule->block() << (*m->block())[i];
216
+ }
217
+
218
+ Block* wrapper_block = new (ctx.mem) Block(m->block() ? m->block()->pstate() : m->pstate());
219
+ *wrapper_block << new_rule;
220
+ At_Rule* mm = new (ctx.mem) At_Rule(m->pstate(),
221
+ m->keyword(),
222
+ m->selector(),
223
+ wrapper_block);
224
+ if (m->value()) mm->value(m->value());
225
+
226
+ Bubble* bubble = new (ctx.mem) Bubble(mm->pstate(), mm);
227
+ return bubble;
228
+ }
229
+
230
+ Statement* Cssize::bubble(At_Root_Block* m)
231
+ {
232
+ Block* bb = new (ctx.mem) Block(this->parent()->pstate());
233
+ Has_Block* new_rule = static_cast<Has_Block*>(shallow_copy(this->parent()));
234
+ new_rule->block(bb);
235
+ new_rule->tabs(this->parent()->tabs());
236
+
237
+ for (size_t i = 0, L = m->block()->length(); i < L; ++i) {
238
+ *new_rule->block() << (*m->block())[i];
239
+ }
240
+
241
+ Block* wrapper_block = new (ctx.mem) Block(m->block()->pstate());
242
+ *wrapper_block << new_rule;
243
+ At_Root_Block* mm = new (ctx.mem) At_Root_Block(m->pstate(),
244
+ wrapper_block,
245
+ m->expression());
246
+
247
+ Bubble* bubble = new (ctx.mem) Bubble(mm->pstate(), mm);
248
+ return bubble;
249
+ }
250
+
251
+ Statement* Cssize::bubble(Feature_Block* m)
252
+ {
253
+ Ruleset* parent = static_cast<Ruleset*>(shallow_copy(this->parent()));
254
+
255
+ Block* bb = new (ctx.mem) Block(parent->block()->pstate());
256
+ Ruleset* new_rule = new (ctx.mem) Ruleset(parent->pstate(),
257
+ parent->selector(),
258
+ bb);
259
+ new_rule->tabs(parent->tabs());
260
+
261
+ for (size_t i = 0, L = m->block()->length(); i < L; ++i) {
262
+ *new_rule->block() << (*m->block())[i];
263
+ }
264
+
265
+ Block* wrapper_block = new (ctx.mem) Block(m->block()->pstate());
266
+ *wrapper_block << new_rule;
267
+ Feature_Block* mm = new (ctx.mem) Feature_Block(m->pstate(),
268
+ m->feature_queries(),
269
+ wrapper_block);
270
+
271
+ Bubble* bubble = new (ctx.mem) Bubble(mm->pstate(), mm);
272
+ return bubble;
273
+ }
274
+
275
+ Statement* Cssize::bubble(Media_Block* m)
276
+ {
277
+ Ruleset* parent = static_cast<Ruleset*>(shallow_copy(this->parent()));
278
+
279
+ Block* bb = new (ctx.mem) Block(parent->block()->pstate());
280
+ Ruleset* new_rule = new (ctx.mem) Ruleset(parent->pstate(),
281
+ parent->selector(),
282
+ bb);
283
+ new_rule->tabs(parent->tabs());
284
+
285
+ for (size_t i = 0, L = m->block()->length(); i < L; ++i) {
286
+ *new_rule->block() << (*m->block())[i];
287
+ }
288
+
289
+ Block* wrapper_block = new (ctx.mem) Block(m->block()->pstate());
290
+ *wrapper_block << new_rule;
291
+ Media_Block* mm = new (ctx.mem) Media_Block(m->pstate(),
292
+ m->media_queries(),
293
+ wrapper_block,
294
+ m->selector());
295
+
296
+ mm->tabs(m->tabs());
297
+
298
+ Bubble* bubble = new (ctx.mem) Bubble(mm->pstate(), mm);
299
+
300
+ return bubble;
301
+ }
302
+
303
+ bool Cssize::bubblable(Statement* s)
304
+ {
305
+ return s->statement_type() == Statement::RULESET || s->bubbles();
306
+ }
307
+
308
+ Statement* Cssize::flatten(Statement* s)
309
+ {
310
+ Block* bb = s->block();
311
+ Block* result = new (ctx.mem) Block(bb->pstate(), 0, bb->is_root());
312
+ for (size_t i = 0, L = bb->length(); i < L; ++i) {
313
+ Statement* ss = (*bb)[i];
314
+ if (ss->block()) {
315
+ ss = flatten(ss);
316
+ for (size_t j = 0, K = ss->block()->length(); j < K; ++j) {
317
+ *result << (*ss->block())[j];
318
+ }
319
+ }
320
+ else {
321
+ *result << ss;
322
+ }
323
+ }
324
+ return result;
325
+ }
326
+
327
+ vector<pair<bool, Block*>> Cssize::slice_by_bubble(Statement* b)
328
+ {
329
+ vector<pair<bool, Block*>> results;
330
+ for (size_t i = 0, L = b->block()->length(); i < L; ++i) {
331
+ Statement* value = (*b->block())[i];
332
+ bool key = value->statement_type() == Statement::BUBBLE;
333
+
334
+ if (!results.empty() && results.back().first == key)
335
+ {
336
+ Block* wrapper_block = results.back().second;
337
+ *wrapper_block << value;
338
+ }
339
+ else
340
+ {
341
+ Block* wrapper_block = new (ctx.mem) Block(value->pstate());
342
+ *wrapper_block << value;
343
+ results.push_back(make_pair(key, wrapper_block));
344
+ }
345
+ }
346
+ return results;
347
+ }
348
+
349
+ Statement* Cssize::shallow_copy(Statement* s)
350
+ {
351
+ switch (s->statement_type())
352
+ {
353
+ case Statement::RULESET:
354
+ return new (ctx.mem) Ruleset(*static_cast<Ruleset*>(s));
355
+ case Statement::MEDIA:
356
+ return new (ctx.mem) Media_Block(*static_cast<Media_Block*>(s));
357
+ case Statement::BUBBLE:
358
+ return new (ctx.mem) Bubble(*static_cast<Bubble*>(s));
359
+ case Statement::DIRECTIVE:
360
+ return new (ctx.mem) At_Rule(*static_cast<At_Rule*>(s));
361
+ case Statement::FEATURE:
362
+ return new (ctx.mem) Feature_Block(*static_cast<Feature_Block*>(s));
363
+ case Statement::ATROOT:
364
+ return new (ctx.mem) At_Root_Block(*static_cast<At_Root_Block*>(s));
365
+ case Statement::KEYFRAMERULE:
366
+ return new (ctx.mem) Keyframe_Rule(*static_cast<Keyframe_Rule*>(s));
367
+ case Statement::NONE:
368
+ default:
369
+ error("unknown internal error; please contact the LibSass maintainers", s->pstate(), backtrace);
370
+ String_Constant* msg = new (ctx.mem) String_Constant(ParserState("[WARN]"), string("`CSSize` can't clone ") + typeid(*s).name());
371
+ return new (ctx.mem) Warning(ParserState("[WARN]"), msg);
372
+ }
373
+ }
374
+
375
+ Statement* Cssize::debubble(Block* children, Statement* parent)
376
+ {
377
+ Has_Block* previous_parent = 0;
378
+ vector<pair<bool, Block*>> baz = slice_by_bubble(children);
379
+ Block* result = new (ctx.mem) Block(children->pstate());
380
+
381
+ for (size_t i = 0, L = baz.size(); i < L; ++i) {
382
+ bool is_bubble = baz[i].first;
383
+ Block* slice = baz[i].second;
384
+
385
+ if (!is_bubble) {
386
+ if (!parent) {
387
+ *result << slice;
388
+ }
389
+ else if (previous_parent) {
390
+ *previous_parent->block() += slice;
391
+ }
392
+ else {
393
+ previous_parent = static_cast<Has_Block*>(shallow_copy(parent));
394
+ previous_parent->tabs(parent->tabs());
395
+
396
+ Has_Block* new_parent = static_cast<Has_Block*>(shallow_copy(parent));
397
+ new_parent->block(slice);
398
+ new_parent->tabs(parent->tabs());
399
+
400
+ *result << new_parent;
401
+ }
402
+ continue;
403
+ }
404
+
405
+ Block* wrapper_block = new (ctx.mem) Block(children->block()->pstate(),
406
+ children->block()->length(),
407
+ children->block()->is_root());
408
+
409
+ for (size_t j = 0, K = slice->length(); j < K; ++j)
410
+ {
411
+ Statement* ss = 0;
412
+ Bubble* b = static_cast<Bubble*>((*slice)[j]);
413
+
414
+ if (!parent ||
415
+ parent->statement_type() != Statement::MEDIA ||
416
+ b->node()->statement_type() != Statement::MEDIA ||
417
+ static_cast<Media_Block*>(b->node())->media_queries() == static_cast<Media_Block*>(parent)->media_queries())
418
+ {
419
+ ss = b->node();
420
+ }
421
+ else
422
+ {
423
+ List* mq = merge_media_queries(static_cast<Media_Block*>(b->node()), static_cast<Media_Block*>(parent));
424
+ static_cast<Media_Block*>(b->node())->media_queries(mq);
425
+ ss = b->node();
426
+ }
427
+
428
+ if (!ss) continue;
429
+
430
+ ss->tabs(ss->tabs() + b->tabs());
431
+ ss->group_end(b->group_end());
432
+
433
+ if (!ss) continue;
434
+
435
+ Block* bb = new (ctx.mem) Block(children->block()->pstate(),
436
+ children->block()->length(),
437
+ children->block()->is_root());
438
+ *bb << ss->perform(this);
439
+ Statement* wrapper = flatten(bb);
440
+ *wrapper_block << wrapper;
441
+
442
+ if (wrapper->block()->length()) {
443
+ previous_parent = 0;
444
+ }
445
+ }
446
+
447
+ if (wrapper_block) {
448
+ *result << flatten(wrapper_block);
449
+ }
450
+ }
451
+
452
+ return flatten(result);
453
+ }
454
+
455
+ Statement* Cssize::fallback_impl(AST_Node* n)
456
+ {
457
+ return static_cast<Statement*>(n);
458
+ }
459
+
460
+ void Cssize::append_block(Block* b)
461
+ {
462
+ Block* current_block = block_stack.back();
463
+
464
+ for (size_t i = 0, L = b->length(); i < L; ++i) {
465
+ Statement* ith = (*b)[i]->perform(this);
466
+ if (ith && ith->block()) {
467
+ for (size_t j = 0, K = ith->block()->length(); j < K; ++j) {
468
+ *current_block << (*ith->block())[j];
469
+ }
470
+ }
471
+ else if (ith) {
472
+ *current_block << ith;
473
+ }
474
+ }
475
+ }
476
+
477
+ List* Cssize::merge_media_queries(Media_Block* m1, Media_Block* m2)
478
+ {
479
+ List* qq = new (ctx.mem) List(m1->media_queries()->pstate(),
480
+ m1->media_queries()->length(),
481
+ List::COMMA);
482
+
483
+ for (size_t i = 0, L = m1->media_queries()->length(); i < L; i++) {
484
+ for (size_t j = 0, K = m2->media_queries()->length(); j < K; j++) {
485
+ Media_Query* mq1 = static_cast<Media_Query*>((*m1->media_queries())[i]);
486
+ Media_Query* mq2 = static_cast<Media_Query*>((*m2->media_queries())[j]);
487
+ Media_Query* mq = merge_media_query(mq1, mq2);
488
+
489
+ if (mq) *qq << mq;
490
+ }
491
+ }
492
+
493
+ return qq;
494
+ }
495
+
496
+
497
+ Media_Query* Cssize::merge_media_query(Media_Query* mq1, Media_Query* mq2)
498
+ {
499
+ To_String to_string(&ctx);
500
+
501
+ string type;
502
+ string mod;
503
+
504
+ string m1 = string(mq1->is_restricted() ? "only" : mq1->is_negated() ? "not" : "");
505
+ string t1 = mq1->media_type() ? mq1->media_type()->perform(&to_string) : "";
506
+ string m2 = string(mq2->is_restricted() ? "only" : mq1->is_negated() ? "not" : "");
507
+ string t2 = mq2->media_type() ? mq2->media_type()->perform(&to_string) : "";
508
+
509
+
510
+ if (t1.empty()) t1 = t2;
511
+ if (t2.empty()) t2 = t1;
512
+
513
+ if ((m1 == "not") ^ (m2 == "not")) {
514
+ if (t1 == t2) {
515
+ return 0;
516
+ }
517
+ type = m1 == "not" ? t2 : t1;
518
+ mod = m1 == "not" ? m2 : m1;
519
+ }
520
+ else if (m1 == "not" && m2 == "not") {
521
+ if (t1 != t2) {
522
+ return 0;
523
+ }
524
+ type = t1;
525
+ mod = "not";
526
+ }
527
+ else if (t1 != t2) {
528
+ return 0;
529
+ } else {
530
+ type = t1;
531
+ mod = m1.empty() ? m2 : m1;
532
+ }
533
+
534
+ Media_Query* mm = new (ctx.mem) Media_Query(
535
+ mq1->pstate(), 0,
536
+ mq1->length() + mq2->length(), mod == "not", mod == "only"
537
+ );
538
+
539
+ if (!type.empty()) {
540
+ mm->media_type(new (ctx.mem) String_Constant(mq1->pstate(), type));
541
+ }
542
+
543
+ *mm += mq2;
544
+ *mm += mq1;
545
+ return mm;
546
+ }
547
+ }