sassc 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
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
+ }