sassc 1.8.3 → 1.8.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -1
  3. data/ext/libsass/.editorconfig +1 -1
  4. data/ext/libsass/.gitignore +1 -0
  5. data/ext/libsass/LICENSE +1 -1
  6. data/ext/libsass/Makefile +20 -14
  7. data/ext/libsass/Makefile.conf +0 -1
  8. data/ext/libsass/Readme.md +3 -1
  9. data/ext/libsass/appveyor.yml +19 -11
  10. data/ext/libsass/docs/api-importer-example.md +2 -1235
  11. data/ext/libsass/docs/build-with-autotools.md +10 -0
  12. data/ext/libsass/docs/build-with-makefiles.md +18 -0
  13. data/ext/libsass/include/sass/base.h +4 -1
  14. data/ext/libsass/include/sass/values.h +2 -1
  15. data/ext/libsass/src/ast.cpp +279 -346
  16. data/ext/libsass/src/ast.hpp +234 -60
  17. data/ext/libsass/src/base64vlq.cpp +1 -0
  18. data/ext/libsass/src/bind.cpp +35 -45
  19. data/ext/libsass/src/bind.hpp +1 -0
  20. data/ext/libsass/src/color_maps.cpp +1 -0
  21. data/ext/libsass/src/constants.cpp +4 -1
  22. data/ext/libsass/src/constants.hpp +2 -1
  23. data/ext/libsass/src/context.cpp +41 -31
  24. data/ext/libsass/src/context.hpp +10 -10
  25. data/ext/libsass/src/cssize.cpp +7 -4
  26. data/ext/libsass/src/cssize.hpp +1 -3
  27. data/ext/libsass/src/debugger.hpp +73 -14
  28. data/ext/libsass/src/emitter.cpp +37 -25
  29. data/ext/libsass/src/emitter.hpp +10 -9
  30. data/ext/libsass/src/environment.cpp +16 -5
  31. data/ext/libsass/src/environment.hpp +5 -3
  32. data/ext/libsass/src/error_handling.cpp +91 -14
  33. data/ext/libsass/src/error_handling.hpp +105 -4
  34. data/ext/libsass/src/eval.cpp +519 -330
  35. data/ext/libsass/src/eval.hpp +12 -13
  36. data/ext/libsass/src/expand.cpp +92 -56
  37. data/ext/libsass/src/expand.hpp +5 -3
  38. data/ext/libsass/src/extend.cpp +60 -51
  39. data/ext/libsass/src/extend.hpp +1 -3
  40. data/ext/libsass/src/file.cpp +37 -27
  41. data/ext/libsass/src/functions.cpp +78 -62
  42. data/ext/libsass/src/functions.hpp +1 -0
  43. data/ext/libsass/src/inspect.cpp +293 -64
  44. data/ext/libsass/src/inspect.hpp +2 -0
  45. data/ext/libsass/src/lexer.cpp +1 -0
  46. data/ext/libsass/src/listize.cpp +14 -15
  47. data/ext/libsass/src/listize.hpp +3 -5
  48. data/ext/libsass/src/memory_manager.cpp +1 -0
  49. data/ext/libsass/src/node.cpp +2 -3
  50. data/ext/libsass/src/operation.hpp +70 -71
  51. data/ext/libsass/src/output.cpp +28 -32
  52. data/ext/libsass/src/output.hpp +1 -2
  53. data/ext/libsass/src/parser.cpp +402 -183
  54. data/ext/libsass/src/parser.hpp +19 -9
  55. data/ext/libsass/src/plugins.cpp +1 -0
  56. data/ext/libsass/src/position.cpp +1 -0
  57. data/ext/libsass/src/prelexer.cpp +134 -56
  58. data/ext/libsass/src/prelexer.hpp +51 -3
  59. data/ext/libsass/src/remove_placeholders.cpp +35 -9
  60. data/ext/libsass/src/remove_placeholders.hpp +4 -3
  61. data/ext/libsass/src/sass.cpp +1 -0
  62. data/ext/libsass/src/sass.hpp +129 -0
  63. data/ext/libsass/src/sass_context.cpp +31 -14
  64. data/ext/libsass/src/sass_context.hpp +2 -31
  65. data/ext/libsass/src/sass_functions.cpp +1 -0
  66. data/ext/libsass/src/sass_interface.cpp +5 -6
  67. data/ext/libsass/src/sass_util.cpp +1 -2
  68. data/ext/libsass/src/sass_util.hpp +5 -5
  69. data/ext/libsass/src/sass_values.cpp +13 -10
  70. data/ext/libsass/src/source_map.cpp +4 -3
  71. data/ext/libsass/src/source_map.hpp +2 -2
  72. data/ext/libsass/src/subset_map.hpp +0 -1
  73. data/ext/libsass/src/to_c.cpp +1 -0
  74. data/ext/libsass/src/to_c.hpp +1 -3
  75. data/ext/libsass/src/to_value.cpp +3 -5
  76. data/ext/libsass/src/to_value.hpp +1 -1
  77. data/ext/libsass/src/units.cpp +96 -59
  78. data/ext/libsass/src/units.hpp +10 -8
  79. data/ext/libsass/src/utf8_string.cpp +5 -0
  80. data/ext/libsass/src/util.cpp +23 -156
  81. data/ext/libsass/src/util.hpp +10 -14
  82. data/ext/libsass/src/values.cpp +1 -0
  83. data/ext/libsass/test/test_node.cpp +2 -6
  84. data/ext/libsass/test/test_selector_difference.cpp +1 -3
  85. data/ext/libsass/test/test_specificity.cpp +0 -2
  86. data/ext/libsass/test/test_superselector.cpp +0 -2
  87. data/ext/libsass/test/test_unification.cpp +1 -3
  88. data/ext/libsass/win/libsass.targets +18 -5
  89. data/ext/libsass/win/libsass.vcxproj +9 -7
  90. data/ext/libsass/win/libsass.vcxproj.filters +148 -106
  91. data/lib/sassc/version.rb +1 -1
  92. data/test/engine_test.rb +12 -0
  93. data/test/native_test.rb +1 -1
  94. metadata +3 -4
  95. data/ext/libsass/src/to_string.cpp +0 -48
  96. data/ext/libsass/src/to_string.hpp +0 -38
@@ -23,11 +23,11 @@ namespace Sass {
23
23
  class Parser : public ParserState {
24
24
  public:
25
25
 
26
- enum Syntactic_Context { nothing, mixin_def, function_def };
26
+ enum Scope { Root, Mixin, Function, Media, Control, Properties, Rules };
27
27
 
28
28
  Context& ctx;
29
29
  std::vector<Block*> block_stack;
30
- std::vector<Syntactic_Context> stack;
30
+ std::vector<Scope> stack;
31
31
  Media_Block* last_media_block;
32
32
  const char* source;
33
33
  const char* position;
@@ -44,14 +44,14 @@ namespace Sass {
44
44
  Parser(Context& ctx, const ParserState& pstate)
45
45
  : ParserState(pstate), ctx(ctx), block_stack(0), stack(0), last_media_block(0),
46
46
  source(0), position(0), end(0), before_token(pstate), after_token(pstate), pstate(pstate), indentation(0)
47
- { in_at_root = false; stack.push_back(nothing); }
47
+ { in_at_root = false; stack.push_back(Scope::Root); }
48
48
 
49
49
  // static Parser from_string(const std::string& src, Context& ctx, ParserState pstate = ParserState("[STRING]"));
50
- static Parser from_c_str(const char* src, Context& ctx, ParserState pstate = ParserState("[CSTRING]"));
51
- static Parser from_c_str(const char* beg, const char* end, Context& ctx, ParserState pstate = ParserState("[CSTRING]"));
52
- static Parser from_token(Token t, Context& ctx, ParserState pstate = ParserState("[TOKEN]"));
50
+ static Parser from_c_str(const char* src, Context& ctx, ParserState pstate = ParserState("[CSTRING]"), const char* source = 0);
51
+ static Parser from_c_str(const char* beg, const char* end, Context& ctx, ParserState pstate = ParserState("[CSTRING]"), const char* source = 0);
52
+ static Parser from_token(Token t, Context& ctx, ParserState pstate = ParserState("[TOKEN]"), const char* source = 0);
53
53
  // special static parsers to convert strings into certain selectors
54
- static Selector_List* parse_selector(const char* src, Context& ctx, ParserState pstate = ParserState("[SELECTOR]"));
54
+ static Selector_List* parse_selector(const char* src, Context& ctx, ParserState pstate = ParserState("[SELECTOR]"), const char* source = 0);
55
55
 
56
56
  #ifdef __clang__
57
57
 
@@ -96,6 +96,15 @@ namespace Sass {
96
96
 
97
97
  }
98
98
 
99
+ // peek will only skip over space, tabs and line comment
100
+ // return the position where the lexer match will occur
101
+ template <Prelexer::prelexer mx>
102
+ const char* match(const char* start = 0)
103
+ {
104
+ // match the given prelexer
105
+ return mx(position);
106
+ }
107
+
99
108
  // peek will only skip over space, tabs and line comment
100
109
  // return the position where the lexer match will occur
101
110
  template <Prelexer::prelexer mx>
@@ -253,6 +262,7 @@ namespace Sass {
253
262
  Function_Call* parse_function_call();
254
263
  Function_Call_Schema* parse_function_call_schema();
255
264
  String* parse_url_function_string();
265
+ String* parse_url_function_argument();
256
266
  String* parse_interpolated_chunk(Token, bool constant = false);
257
267
  String* parse_string();
258
268
  String_Constant* parse_static_expression();
@@ -298,8 +308,8 @@ namespace Sass {
298
308
  Lookahead lookahead_for_selector(const char* start = 0);
299
309
  Lookahead lookahead_for_include(const char* start = 0);
300
310
 
301
- Expression* fold_operands(Expression* base, std::vector<Expression*>& operands, Sass_OP op);
302
- Expression* fold_operands(Expression* base, std::vector<Expression*>& operands, std::vector<Sass_OP>& ops);
311
+ Expression* fold_operands(Expression* base, std::vector<Expression*>& operands, Operand op);
312
+ Expression* fold_operands(Expression* base, std::vector<Expression*>& operands, std::vector<Operand>& ops, size_t i = 0);
303
313
 
304
314
  void throw_syntax_error(std::string message, size_t ln = 0);
305
315
  void throw_read_error(std::string message, size_t ln = 0);
@@ -7,6 +7,7 @@
7
7
  #include <dlfcn.h>
8
8
  #endif
9
9
 
10
+ #include "sass.hpp"
10
11
  #include <iostream>
11
12
  #include "output.hpp"
12
13
  #include "plugins.hpp"
@@ -1,3 +1,4 @@
1
+ #include "sass.hpp"
1
2
  #include "position.hpp"
2
3
 
3
4
  namespace Sass {
@@ -1,3 +1,4 @@
1
+ #include "sass.hpp"
1
2
  #include <cctype>
2
3
  #include <cstddef>
3
4
  #include <iostream>
@@ -153,8 +154,8 @@ namespace Sass {
153
154
  >(src);
154
155
  }
155
156
 
156
- // Match CSS unit identifier.
157
- const char* unit_identifier(const char* src)
157
+ // Match a single CSS unit
158
+ const char* one_unit(const char* src)
158
159
  {
159
160
  return sequence <
160
161
  optional < exactly <'-'> >,
@@ -169,6 +170,34 @@ namespace Sass {
169
170
  >(src);
170
171
  }
171
172
 
173
+ // Match numerator/denominator CSS units
174
+ const char* multiple_units(const char* src)
175
+ {
176
+ return
177
+ sequence <
178
+ one_unit,
179
+ zero_plus <
180
+ sequence <
181
+ exactly <'*'>,
182
+ one_unit
183
+ >
184
+ >
185
+ >(src);
186
+ }
187
+
188
+ // Match complex CSS unit identifiers
189
+ const char* unit_identifier(const char* src)
190
+ {
191
+ return sequence <
192
+ multiple_units,
193
+ optional <
194
+ sequence <
195
+ exactly <'/'>,
196
+ multiple_units
197
+ > >
198
+ >(src);
199
+ }
200
+
172
201
  const char* identifier_alnums(const char* src)
173
202
  {
174
203
  return one_plus< identifier_alnum >(src);
@@ -194,7 +223,12 @@ namespace Sass {
194
223
  sequence <
195
224
  zero_plus <
196
225
  alternatives <
197
- identifier,
226
+ sequence <
227
+ optional <
228
+ exactly <'$'>
229
+ >,
230
+ identifier
231
+ >,
198
232
  exactly <'-'>
199
233
  >
200
234
  >,
@@ -202,9 +236,13 @@ namespace Sass {
202
236
  zero_plus <
203
237
  alternatives <
204
238
  digits,
205
- identifier,
239
+ sequence <
240
+ optional <
241
+ exactly <'$'>
242
+ >,
243
+ identifier
244
+ >,
206
245
  quoted_string,
207
- exactly<'+'>,
208
246
  exactly<'-'>
209
247
  >
210
248
  >
@@ -278,18 +316,54 @@ namespace Sass {
278
316
  >(src);
279
317
  }
280
318
 
281
- const char* value_schema(const char* src) {
282
- // follows this pattern: ([xyz]*i[xyz]*)+
283
- return one_plus< sequence< zero_plus< alternatives< identifier, percentage, dimension, hex, number, quoted_string > >,
284
- interpolant,
285
- zero_plus< alternatives< identifier, percentage, dimension, hex, number, quoted_string, exactly<'%'> > > > >(src);
319
+ const char* sass_value(const char* src) {
320
+ return alternatives <
321
+ quoted_string,
322
+ identifier,
323
+ percentage,
324
+ hex,
325
+ dimension,
326
+ number
327
+ >(src);
286
328
  }
287
329
 
288
- /* not used anymore - remove?
289
- const char* filename(const char* src) {
290
- return one_plus< alternatives< identifier, number, exactly<'.'> > >(src);
330
+ // this is basically `one_plus < sass_value >`
331
+ // takes care to not parse invalid combinations
332
+ const char* value_combinations(const char* src) {
333
+ // `2px-2px` is invalid combo
334
+ bool was_number = false;
335
+ const char* pos = src;
336
+ while (src) {
337
+ if ((pos = alternatives < quoted_string, identifier, percentage, hex >(src))) {
338
+ was_number = false;
339
+ src = pos;
340
+ } else if (!was_number && !exactly<'+'>(src) && (pos = alternatives < dimension, number >(src))) {
341
+ was_number = true;
342
+ src = pos;
343
+ } else {
344
+ break;
345
+ }
346
+ }
347
+ return src;
348
+ }
349
+
350
+ // must be at least one interpolant
351
+ // can be surrounded by sass values
352
+ // make sure to never parse (dim)(dim)
353
+ // since this wrongly consumes `2px-1px`
354
+ // `2px1px` is valid number (unit `px1px`)
355
+ const char* value_schema(const char* src)
356
+ {
357
+ return sequence <
358
+ one_plus <
359
+ sequence <
360
+ optional < value_combinations >,
361
+ interpolant,
362
+ optional < value_combinations >
363
+ >
364
+ >
365
+ >(src);
291
366
  }
292
- */
293
367
 
294
368
  // Match CSS '@' keywords.
295
369
  const char* at_keyword(const char* src) {
@@ -539,6 +613,9 @@ namespace Sass {
539
613
  }
540
614
  // Match CSS numeric constants.
541
615
 
616
+ const char* op(const char* src) {
617
+ return class_char<op_chars>(src);
618
+ }
542
619
  const char* sign(const char* src) {
543
620
  return class_char<sign_chars>(src);
544
621
  }
@@ -603,23 +680,19 @@ namespace Sass {
603
680
  // Match CSS uri specifiers.
604
681
 
605
682
  const char* uri_prefix(const char* src) {
606
- return exactly<url_kwd>(src);
607
- }
608
- const char* uri_value(const char* src)
609
- {
610
- return
611
- sequence <
612
- negate <
613
- exactly < '$' >
683
+ return sequence <
684
+ exactly <
685
+ url_kwd
614
686
  >,
615
687
  zero_plus <
616
- alternatives <
617
- alnum,
618
- interpolant,
619
- exactly <'/'>,
620
- class_char < uri_chars >
688
+ sequence <
689
+ exactly <'-'>,
690
+ one_plus <
691
+ alpha
692
+ >
621
693
  >
622
- >
694
+ >,
695
+ exactly <'('>
623
696
  >(src);
624
697
  }
625
698
 
@@ -1107,34 +1180,39 @@ namespace Sass {
1107
1180
  return sequence< number, optional_spaces, exactly<'/'>, optional_spaces, number >(src);
1108
1181
  }
1109
1182
 
1110
- template <size_t size, prelexer mx, prelexer pad>
1111
- const char* padded_token(const char* src)
1112
- {
1113
- size_t got = 0;
1114
- const char* pos = src;
1115
- while (got < size) {
1116
- if (!mx(pos)) break;
1117
- ++ pos; ++ got;
1118
- }
1119
- while (got < size) {
1120
- if (!pad(pos)) break;
1121
- ++ pos; ++ got;
1122
- }
1123
- return got ? pos : 0;
1124
- }
1125
-
1126
- template <size_t min, size_t max, prelexer mx>
1127
- const char* minmax_range(const char* src)
1128
- {
1129
- size_t got = 0;
1130
- const char* pos = src;
1131
- while (got < max) {
1132
- if (!mx(pos)) break;
1133
- ++ pos; ++ got;
1134
- }
1135
- if (got < min) return 0;
1136
- if (got > max) return 0;
1137
- return pos;
1183
+ // lexer special_fn: these functions cannot be overloaded
1184
+ // (/((-[\w-]+-)?(calc|element)|expression|progid:[a-z\.]*)\(/i)
1185
+ const char* re_special_fun(const char* src) {
1186
+ return sequence <
1187
+ optional <
1188
+ sequence <
1189
+ exactly <'-'>,
1190
+ one_plus <
1191
+ alternatives <
1192
+ alpha,
1193
+ exactly <'+'>,
1194
+ exactly <'-'>
1195
+ >
1196
+ >
1197
+ >
1198
+ >,
1199
+ alternatives <
1200
+ exactly < calc_fn_kwd >,
1201
+ exactly < expression_kwd >,
1202
+ sequence <
1203
+ sequence <
1204
+ exactly < progid_kwd >,
1205
+ exactly <':'>
1206
+ >,
1207
+ zero_plus <
1208
+ alternatives <
1209
+ char_range <'a', 'z'>,
1210
+ exactly <'.'>
1211
+ >
1212
+ >
1213
+ >
1214
+ >
1215
+ >(src);
1138
1216
  }
1139
1217
 
1140
1218
  }
@@ -200,6 +200,8 @@ namespace Sass {
200
200
  const char* strict_identifier_alpha(const char* src);
201
201
  const char* strict_identifier_alnum(const char* src);
202
202
  // Match a CSS unit identifier.
203
+ const char* one_unit(const char* src);
204
+ const char* multiple_units(const char* src);
203
205
  const char* unit_identifier(const char* src);
204
206
  // const char* strict_identifier_alnums(const char* src);
205
207
  // Match reference selector.
@@ -210,6 +212,7 @@ namespace Sass {
210
212
  // Match interpolant schemas
211
213
  const char* identifier_schema(const char* src);
212
214
  const char* value_schema(const char* src);
215
+ const char* sass_value(const char* src);
213
216
  // const char* filename(const char* src);
214
217
  // const char* filename_schema(const char* src);
215
218
  // const char* url_schema(const char* src);
@@ -252,6 +255,7 @@ namespace Sass {
252
255
  const char* re_nothing(const char* src);
253
256
  const char* re_type_selector2(const char* src);
254
257
 
258
+ const char* re_special_fun(const char* src);
255
259
 
256
260
  const char* kwd_warn(const char* src);
257
261
  const char* kwd_err(const char* src);
@@ -282,6 +286,7 @@ namespace Sass {
282
286
  // Match placeholder selectors.
283
287
  const char* placeholder(const char* src);
284
288
  // Match CSS numeric constants.
289
+ const char* op(const char* src);
285
290
  const char* sign(const char* src);
286
291
  const char* unsigned_number(const char* src);
287
292
  const char* number(const char* src);
@@ -296,7 +301,6 @@ namespace Sass {
296
301
  // const char* rgb_prefix(const char* src);
297
302
  // Match CSS uri specifiers.
298
303
  const char* uri_prefix(const char* src);
299
- const char* uri_value(const char* src);
300
304
  // Match CSS "!important" keyword.
301
305
  const char* kwd_important(const char* src);
302
306
  // Match CSS "!optional" keyword.
@@ -381,6 +385,18 @@ namespace Sass {
381
385
  }
382
386
  return 0;
383
387
  }
388
+ template<prelexer mx, prelexer skip>
389
+ const char* find_first_in_interval(const char* beg, const char* end) {
390
+ bool esc = false;
391
+ while ((beg < end) && *beg) {
392
+ if (esc) esc = false;
393
+ else if (*beg == '\\') esc = true;
394
+ else if (const char* pos = skip(beg)) beg = pos;
395
+ else if (mx(beg)) return beg;
396
+ ++beg;
397
+ }
398
+ return 0;
399
+ }
384
400
  template <prelexer mx>
385
401
  unsigned int count_interval(const char* beg, const char* end) {
386
402
  unsigned int counter = 0;
@@ -405,10 +421,42 @@ namespace Sass {
405
421
  }
406
422
 
407
423
  template <size_t size, prelexer mx, prelexer pad>
408
- const char* padded_token(const char* src);
424
+ const char* padded_token(const char* src)
425
+ {
426
+ size_t got = 0;
427
+ const char* pos = src;
428
+ while (got < size) {
429
+ if (!mx(pos)) break;
430
+ ++ pos; ++ got;
431
+ }
432
+ while (got < size) {
433
+ if (!pad(pos)) break;
434
+ ++ pos; ++ got;
435
+ }
436
+ return got ? pos : 0;
437
+ }
409
438
 
410
439
  template <size_t min, size_t max, prelexer mx>
411
- const char* minmax_range(const char* src);
440
+ const char* minmax_range(const char* src)
441
+ {
442
+ size_t got = 0;
443
+ const char* pos = src;
444
+ while (got < max) {
445
+ if (!mx(pos)) break;
446
+ ++ pos; ++ got;
447
+ }
448
+ if (got < min) return 0;
449
+ if (got > max) return 0;
450
+ return pos;
451
+ }
452
+
453
+ template <char min, char max>
454
+ const char* char_range(const char* src)
455
+ {
456
+ if (*src < min) return 0;
457
+ if (*src > max) return 0;
458
+ return src + 1;
459
+ }
412
460
 
413
461
  }
414
462
  }
@@ -1,7 +1,7 @@
1
+ #include "sass.hpp"
1
2
  #include "remove_placeholders.hpp"
2
3
  #include "context.hpp"
3
4
  #include "inspect.hpp"
4
- #include "to_string.hpp"
5
5
  #include <iostream>
6
6
 
7
7
  namespace Sass {
@@ -16,21 +16,47 @@ namespace Sass {
16
16
  }
17
17
  }
18
18
 
19
+ Selector_List* Remove_Placeholders::remove_placeholders(Selector_List* sl)
20
+ {
21
+ Selector_List* new_sl = SASS_MEMORY_NEW(ctx.mem, Selector_List, sl->pstate());
22
+
23
+ for (size_t i = 0, L = sl->length(); i < L; ++i) {
24
+ if (!(*sl)[i]->contains_placeholder()) {
25
+ *new_sl << (*sl)[i];
26
+ }
27
+ }
28
+
29
+ return new_sl;
30
+
31
+ }
32
+
33
+
19
34
  void Remove_Placeholders::operator()(Ruleset* r) {
20
35
  // Create a new selector group without placeholders
21
36
  Selector_List* sl = static_cast<Selector_List*>(r->selector());
22
37
 
23
38
  if (sl) {
24
- Selector_List* new_sl = SASS_MEMORY_NEW(ctx.mem, Selector_List, sl->pstate());
25
-
26
- for (size_t i = 0, L = sl->length(); i < L; ++i) {
27
- if (!(*sl)[i]->contains_placeholder()) {
28
- *new_sl << (*sl)[i];
39
+ // Set the new placeholder selector list
40
+ r->selector(remove_placeholders(sl));
41
+ // Remove placeholders in wrapped selectors
42
+ for (Complex_Selector* cs : *sl) {
43
+ while (cs) {
44
+ if (cs->head()) {
45
+ for (Simple_Selector* ss : *cs->head()) {
46
+ if (Wrapped_Selector* ws = dynamic_cast<Wrapped_Selector*>(ss)) {
47
+ if (Selector_List* sl = dynamic_cast<Selector_List*>(ws->selector())) {
48
+ Selector_List* clean = remove_placeholders(sl);
49
+ // also clean superflous parent selectors
50
+ // probably not really the correct place
51
+ clean->remove_parent_selectors();
52
+ ws->selector(clean);
53
+ }
54
+ }
29
55
  }
56
+ }
57
+ cs = cs->tail();
30
58
  }
31
-
32
- // Set the new placeholder selector list
33
- r->selector(new_sl);
59
+ }
34
60
  }
35
61
 
36
62
  // Iterate into child blocks