less 4.1.3 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/.eslintrc.js +63 -0
  2. package/Gruntfile.js +1 -1
  3. package/LICENSE +177 -0
  4. package/dist/less.js +7129 -6972
  5. package/dist/less.min.js +3 -3
  6. package/dist/less.min.js.map +1 -1
  7. package/lib/less/contexts.js +1 -1
  8. package/lib/less/contexts.js.map +1 -1
  9. package/lib/less/default-options.js +0 -1
  10. package/lib/less/default-options.js.map +1 -1
  11. package/lib/less/environment/abstract-file-manager.js +9 -3
  12. package/lib/less/environment/abstract-file-manager.js.map +1 -1
  13. package/lib/less/environment/environment-api.js +0 -25
  14. package/lib/less/environment/environment-api.js.map +1 -1
  15. package/lib/less/environment/environment.js +1 -1
  16. package/lib/less/environment/environment.js.map +1 -1
  17. package/lib/less/environment/file-manager-api.js +0 -103
  18. package/lib/less/environment/file-manager-api.js.map +1 -1
  19. package/lib/less/functions/color-blending.js +1 -0
  20. package/lib/less/functions/color-blending.js.map +1 -1
  21. package/lib/less/functions/color.js +19 -19
  22. package/lib/less/functions/color.js.map +1 -1
  23. package/lib/less/functions/default.js +2 -1
  24. package/lib/less/functions/default.js.map +1 -1
  25. package/lib/less/functions/function-registry.js +1 -0
  26. package/lib/less/functions/function-registry.js.map +1 -1
  27. package/lib/less/functions/list.js +2 -2
  28. package/lib/less/functions/list.js.map +1 -1
  29. package/lib/less/functions/math-helper.js +1 -1
  30. package/lib/less/functions/math-helper.js.map +1 -1
  31. package/lib/less/functions/math.js +1 -0
  32. package/lib/less/functions/math.js.map +1 -1
  33. package/lib/less/functions/number.js +4 -3
  34. package/lib/less/functions/number.js.map +1 -1
  35. package/lib/less/functions/svg.js +1 -1
  36. package/lib/less/functions/svg.js.map +1 -1
  37. package/lib/less/import-manager.js +0 -1
  38. package/lib/less/import-manager.js.map +1 -1
  39. package/lib/less/index.js +0 -1
  40. package/lib/less/index.js.map +1 -1
  41. package/lib/less/less-error.js +1 -2
  42. package/lib/less/less-error.js.map +1 -1
  43. package/lib/less/parse-tree.js +1 -2
  44. package/lib/less/parse-tree.js.map +1 -1
  45. package/lib/less/parse.js +1 -2
  46. package/lib/less/parse.js.map +1 -1
  47. package/lib/less/parser/chunker.js +0 -1
  48. package/lib/less/parser/chunker.js.map +1 -1
  49. package/lib/less/parser/parser-input.js +10 -4
  50. package/lib/less/parser/parser-input.js.map +1 -1
  51. package/lib/less/parser/parser.js +105 -89
  52. package/lib/less/parser/parser.js.map +1 -1
  53. package/lib/less/render.js +1 -2
  54. package/lib/less/render.js.map +1 -1
  55. package/lib/less/source-map-builder.js +0 -1
  56. package/lib/less/source-map-builder.js.map +1 -1
  57. package/lib/less/source-map-output.js +1 -1
  58. package/lib/less/source-map-output.js.map +1 -1
  59. package/lib/less/transform-tree.js +0 -1
  60. package/lib/less/transform-tree.js.map +1 -1
  61. package/lib/less/tree/atrule-syntax.js +10 -0
  62. package/lib/less/tree/atrule-syntax.js.map +1 -0
  63. package/lib/less/tree/attribute.js +1 -1
  64. package/lib/less/tree/attribute.js.map +1 -1
  65. package/lib/less/tree/call.js +1 -0
  66. package/lib/less/tree/call.js.map +1 -1
  67. package/lib/less/tree/color.js +2 -0
  68. package/lib/less/tree/color.js.map +1 -1
  69. package/lib/less/tree/container.js +48 -0
  70. package/lib/less/tree/container.js.map +1 -0
  71. package/lib/less/tree/debug-info.js +2 -2
  72. package/lib/less/tree/debug-info.js.map +1 -1
  73. package/lib/less/tree/dimension.js +4 -2
  74. package/lib/less/tree/dimension.js.map +1 -1
  75. package/lib/less/tree/extend.js +2 -0
  76. package/lib/less/tree/extend.js.map +1 -1
  77. package/lib/less/tree/import.js +1 -1
  78. package/lib/less/tree/import.js.map +1 -1
  79. package/lib/less/tree/index.js +4 -0
  80. package/lib/less/tree/index.js.map +1 -1
  81. package/lib/less/tree/js-eval-node.js +1 -1
  82. package/lib/less/tree/js-eval-node.js.map +1 -1
  83. package/lib/less/tree/media.js +4 -88
  84. package/lib/less/tree/media.js.map +1 -1
  85. package/lib/less/tree/namespace-value.js +1 -1
  86. package/lib/less/tree/namespace-value.js.map +1 -1
  87. package/lib/less/tree/nested-at-rule.js +91 -0
  88. package/lib/less/tree/nested-at-rule.js.map +1 -0
  89. package/lib/less/tree/node.js +6 -4
  90. package/lib/less/tree/node.js.map +1 -1
  91. package/lib/less/tree/query-in-parens.js +41 -0
  92. package/lib/less/tree/query-in-parens.js.map +1 -0
  93. package/lib/less/tree/quoted.js +1 -1
  94. package/lib/less/tree/quoted.js.map +1 -1
  95. package/lib/less/tree/ruleset.js +7 -4
  96. package/lib/less/tree/ruleset.js.map +1 -1
  97. package/lib/less/tree/selector.js +5 -3
  98. package/lib/less/tree/selector.js.map +1 -1
  99. package/lib/less/tree/unit.js +3 -1
  100. package/lib/less/tree/unit.js.map +1 -1
  101. package/lib/less/tree/url.js +1 -1
  102. package/lib/less/tree/url.js.map +1 -1
  103. package/lib/less/utils.js +7 -3
  104. package/lib/less/utils.js.map +1 -1
  105. package/lib/less/visitors/extend-visitor.js +4 -0
  106. package/lib/less/visitors/extend-visitor.js.map +1 -1
  107. package/lib/less/visitors/import-visitor.js +4 -0
  108. package/lib/less/visitors/import-visitor.js.map +1 -1
  109. package/lib/less/visitors/join-selector-visitor.js +4 -0
  110. package/lib/less/visitors/join-selector-visitor.js.map +1 -1
  111. package/lib/less/visitors/to-css-visitor.js +6 -2
  112. package/lib/less/visitors/to-css-visitor.js.map +1 -1
  113. package/lib/less-browser/bootstrap.js +3 -4
  114. package/lib/less-browser/bootstrap.js.map +1 -1
  115. package/lib/less-browser/cache.js +1 -1
  116. package/lib/less-browser/cache.js.map +1 -1
  117. package/lib/less-browser/error-reporting.js +2 -2
  118. package/lib/less-browser/error-reporting.js.map +1 -1
  119. package/lib/less-browser/file-manager.js +1 -2
  120. package/lib/less-browser/file-manager.js.map +1 -1
  121. package/lib/less-browser/index.js +6 -2
  122. package/lib/less-browser/index.js.map +1 -1
  123. package/lib/less-browser/plugin-loader.js +3 -2
  124. package/lib/less-browser/plugin-loader.js.map +1 -1
  125. package/lib/less-browser/utils.js +4 -4
  126. package/lib/less-browser/utils.js.map +1 -1
  127. package/lib/less-node/file-manager.js +16 -16
  128. package/lib/less-node/file-manager.js.map +1 -1
  129. package/lib/less-node/lessc-helper.js +1 -0
  130. package/lib/less-node/lessc-helper.js.map +1 -1
  131. package/lib/less-node/url-file-manager.js +5 -0
  132. package/lib/less-node/url-file-manager.js.map +1 -1
  133. package/package.json +9 -6
  134. package/test/browser/generator/benchmark.config.js +19 -19
  135. package/test/browser/generator/runner.config.js +69 -69
  136. package/test/browser/runner-rewrite-urls-spec.js +1 -1
  137. package/test/index.js +2 -0
  138. package/test/less-test.js +33 -9
  139. package/test/plugins/filemanager/index.js +1 -1
  140. package/test/sourcemaps-variable-selector/basic.json +1 -0
  141. package/test/test-es6.ts +5 -5
  142. package/tsconfig.build.json +7 -0
  143. package/tsconfig.json +4 -3
  144. package/.eslintrc.json +0 -71
@@ -7,6 +7,7 @@ var visitors_1 = tslib_1.__importDefault(require("../visitors"));
7
7
  var parser_input_1 = tslib_1.__importDefault(require("./parser-input"));
8
8
  var utils = tslib_1.__importStar(require("../utils"));
9
9
  var function_registry_1 = tslib_1.__importDefault(require("../functions/function-registry"));
10
+ var atrule_syntax_1 = require("../tree/atrule-syntax");
10
11
  //
11
12
  // less.js - parser
12
13
  //
@@ -39,7 +40,8 @@ var function_registry_1 = tslib_1.__importDefault(require("../functions/function
39
40
  // a terminal string or regexp, or a non-terminal function to call.
40
41
  // It also takes care of moving all the indices forwards.
41
42
  //
42
- var Parser = function Parser(context, imports, fileInfo) {
43
+ var Parser = function Parser(context, imports, fileInfo, currentIndex) {
44
+ currentIndex = currentIndex || 0;
43
45
  var parsers;
44
46
  var parserInput = parser_input_1.default();
45
47
  function error(msg, type) {
@@ -82,7 +84,7 @@ var Parser = function Parser(context, imports, fileInfo) {
82
84
  * @param {Number} currentIndex - start number to begin indexing
83
85
  * @param {Object} fileInfo - fileInfo to attach to created nodes
84
86
  */
85
- function parseNode(str, parseList, currentIndex, fileInfo, callback) {
87
+ function parseNode(str, parseList, callback) {
86
88
  var result;
87
89
  var returnNodes = [];
88
90
  var parser = parserInput;
@@ -93,20 +95,9 @@ var Parser = function Parser(context, imports, fileInfo) {
93
95
  index: index + currentIndex
94
96
  });
95
97
  });
96
- for (var x = 0, p = void 0, i = void 0; (p = parseList[x]); x++) {
97
- i = parser.i;
98
+ for (var x = 0, p = void 0; (p = parseList[x]); x++) {
98
99
  result = parsers[p]();
99
- if (result) {
100
- try {
101
- result._index = i + currentIndex;
102
- result._fileInfo = fileInfo;
103
- }
104
- catch (e) { }
105
- returnNodes.push(result);
106
- }
107
- else {
108
- returnNodes.push(null);
109
- }
100
+ returnNodes.push(result || null);
110
101
  }
111
102
  var endInfo = parser.end();
112
103
  if (endInfo.isFinished) {
@@ -153,7 +144,6 @@ var Parser = function Parser(context, imports, fileInfo) {
153
144
  }
154
145
  };
155
146
  }
156
- ;
157
147
  globalVars = (additionalData && additionalData.globalVars) ? Parser.serializeVars(additionalData.globalVars) + "\n" : '';
158
148
  modifyVars = (additionalData && additionalData.modifyVars) ? "\n" + Parser.serializeVars(additionalData.modifyVars) : '';
159
149
  if (context.pluginManager) {
@@ -336,7 +326,7 @@ var Parser = function Parser(context, imports, fileInfo) {
336
326
  comment: function () {
337
327
  if (parserInput.commentStore.length) {
338
328
  var comment = parserInput.commentStore.shift();
339
- return new (tree_1.default.Comment)(comment.text, comment.isLineComment, comment.index, fileInfo);
329
+ return new (tree_1.default.Comment)(comment.text, comment.isLineComment, comment.index + currentIndex, fileInfo);
340
330
  }
341
331
  },
342
332
  //
@@ -369,7 +359,7 @@ var Parser = function Parser(context, imports, fileInfo) {
369
359
  return;
370
360
  }
371
361
  parserInput.forget();
372
- return new (tree_1.default.Quoted)(str.charAt(0), str.substr(1, str.length - 2), isEscaped, index, fileInfo);
362
+ return new (tree_1.default.Quoted)(str.charAt(0), str.substr(1, str.length - 2), isEscaped, index + currentIndex, fileInfo);
373
363
  },
374
364
  //
375
365
  // A catch-all word, such as:
@@ -399,7 +389,7 @@ var Parser = function Parser(context, imports, fileInfo) {
399
389
  return;
400
390
  }
401
391
  parserInput.save();
402
- name = parserInput.$re(/^([\w-]+|%|~|progid:[\w\.]+)\(/);
392
+ name = parserInput.$re(/^([\w-]+|%|~|progid:[\w.]+)\(/);
403
393
  if (!name) {
404
394
  parserInput.forget();
405
395
  return;
@@ -419,7 +409,7 @@ var Parser = function Parser(context, imports, fileInfo) {
419
409
  return;
420
410
  }
421
411
  parserInput.forget();
422
- return new (tree_1.default.Call)(name, args, index, fileInfo);
412
+ return new (tree_1.default.Call)(name, args, index + currentIndex, fileInfo);
423
413
  },
424
414
  //
425
415
  // Parsing rules for functions with non-standard args, e.g.:
@@ -441,7 +431,7 @@ var Parser = function Parser(context, imports, fileInfo) {
441
431
  function f(parse, stop) {
442
432
  return {
443
433
  parse: parse,
444
- stop: stop // when true - stop after parse() and return its result,
434
+ stop: stop // when true - stop after parse() and return its result,
445
435
  // otherwise continue for plain args
446
436
  };
447
437
  }
@@ -532,13 +522,13 @@ var Parser = function Parser(context, imports, fileInfo) {
532
522
  return;
533
523
  }
534
524
  value = this.quoted() || this.variable() || this.property() ||
535
- parserInput.$re(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || '';
525
+ parserInput.$re(/^(?:(?:\\[()'"])|[^()'"])+/) || '';
536
526
  parserInput.autoCommentAbsorb = true;
537
527
  expectChar(')');
538
- return new (tree_1.default.URL)((value.value != null ||
528
+ return new (tree_1.default.URL)((value.value !== undefined ||
539
529
  value instanceof tree_1.default.Variable ||
540
530
  value instanceof tree_1.default.Property) ?
541
- value : new (tree_1.default.Anonymous)(value, index), index, fileInfo);
531
+ value : new (tree_1.default.Anonymous)(value, index), index + currentIndex, fileInfo);
542
532
  },
543
533
  //
544
534
  // A Variable entity, such as `@fink`, in
@@ -564,7 +554,7 @@ var Parser = function Parser(context, imports, fileInfo) {
564
554
  }
565
555
  }
566
556
  parserInput.forget();
567
- return new (tree_1.default.Variable)(name, index, fileInfo);
557
+ return new (tree_1.default.Variable)(name, index + currentIndex, fileInfo);
568
558
  }
569
559
  parserInput.restore();
570
560
  },
@@ -573,7 +563,7 @@ var Parser = function Parser(context, imports, fileInfo) {
573
563
  var curly;
574
564
  var index = parserInput.i;
575
565
  if (parserInput.currentChar() === '@' && (curly = parserInput.$re(/^@\{([\w-]+)\}/))) {
576
- return new (tree_1.default.Variable)("@" + curly[1], index, fileInfo);
566
+ return new (tree_1.default.Variable)("@" + curly[1], index + currentIndex, fileInfo);
577
567
  }
578
568
  },
579
569
  //
@@ -585,7 +575,7 @@ var Parser = function Parser(context, imports, fileInfo) {
585
575
  var name;
586
576
  var index = parserInput.i;
587
577
  if (parserInput.currentChar() === '$' && (name = parserInput.$re(/^\$[\w-]+/))) {
588
- return new (tree_1.default.Property)(name, index, fileInfo);
578
+ return new (tree_1.default.Property)(name, index + currentIndex, fileInfo);
589
579
  }
590
580
  },
591
581
  // A property entity useing the protective {} e.g. ${prop}
@@ -593,7 +583,7 @@ var Parser = function Parser(context, imports, fileInfo) {
593
583
  var curly;
594
584
  var index = parserInput.i;
595
585
  if (parserInput.currentChar() === '$' && (curly = parserInput.$re(/^\$\{([\w-]+)\}/))) {
596
- return new (tree_1.default.Property)("$" + curly[1], index, fileInfo);
586
+ return new (tree_1.default.Property)("$" + curly[1], index + currentIndex, fileInfo);
597
587
  }
598
588
  },
599
589
  //
@@ -606,7 +596,7 @@ var Parser = function Parser(context, imports, fileInfo) {
606
596
  color: function () {
607
597
  var rgb;
608
598
  parserInput.save();
609
- if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})([\w.#\[])?/))) {
599
+ if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})([\w.#[])?/))) {
610
600
  if (!rgb[2]) {
611
601
  parserInput.forget();
612
602
  return new (tree_1.default.Color)(rgb[1], undefined, rgb[0]);
@@ -652,7 +642,7 @@ var Parser = function Parser(context, imports, fileInfo) {
652
642
  //
653
643
  unicodeDescriptor: function () {
654
644
  var ud;
655
- ud = parserInput.$re(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/);
645
+ ud = parserInput.$re(/^U\+[0-9a-fA-F?]+(-[0-9a-fA-F?]+)?/);
656
646
  if (ud) {
657
647
  return new (tree_1.default.UnicodeDescriptor)(ud[0]);
658
648
  }
@@ -675,7 +665,7 @@ var Parser = function Parser(context, imports, fileInfo) {
675
665
  js = parserInput.$re(/^[^`]*`/);
676
666
  if (js) {
677
667
  parserInput.forget();
678
- return new (tree_1.default.JavaScript)(js.substr(0, js.length - 1), Boolean(escape), index, fileInfo);
668
+ return new (tree_1.default.JavaScript)(js.substr(0, js.length - 1), Boolean(escape), index + currentIndex, fileInfo);
679
669
  }
680
670
  parserInput.restore('invalid javascript definition');
681
671
  }
@@ -759,7 +749,7 @@ var Parser = function Parser(context, imports, fileInfo) {
759
749
  if (!elements) {
760
750
  error('Missing target selector for :extend().');
761
751
  }
762
- extend = new (tree_1.default.Extend)(new (tree_1.default.Selector)(elements), option, index, fileInfo);
752
+ extend = new (tree_1.default.Extend)(new (tree_1.default.Selector)(elements), option, index + currentIndex, fileInfo);
763
753
  if (extendList) {
764
754
  extendList.push(extend);
765
755
  }
@@ -835,7 +825,7 @@ var Parser = function Parser(context, imports, fileInfo) {
835
825
  }
836
826
  if (inValue || parsers.end()) {
837
827
  parserInput.forget();
838
- var mixin = new (tree_1.default.mixin.Call)(elements, args, index, fileInfo, !lookups && important);
828
+ var mixin = new (tree_1.default.mixin.Call)(elements, args, index + currentIndex, fileInfo, !lookups && important);
839
829
  if (lookups) {
840
830
  return new tree_1.default.NamespaceValue(mixin, lookups);
841
831
  }
@@ -863,7 +853,7 @@ var Parser = function Parser(context, imports, fileInfo) {
863
853
  if (!e) {
864
854
  break;
865
855
  }
866
- elem = new (tree_1.default.Element)(c, e, false, elemIndex, fileInfo);
856
+ elem = new (tree_1.default.Element)(c, e, false, elemIndex + currentIndex, fileInfo);
867
857
  if (elements) {
868
858
  elements.push(elem);
869
859
  }
@@ -1056,14 +1046,12 @@ var Parser = function Parser(context, imports, fileInfo) {
1056
1046
  },
1057
1047
  ruleLookups: function () {
1058
1048
  var rule;
1059
- var args;
1060
1049
  var lookups = [];
1061
1050
  if (parserInput.currentChar() !== '[') {
1062
1051
  return;
1063
1052
  }
1064
1053
  while (true) {
1065
1054
  parserInput.save();
1066
- args = null;
1067
1055
  rule = this.lookupValue();
1068
1056
  if (!rule && rule !== '') {
1069
1057
  parserInput.restore();
@@ -1150,9 +1138,10 @@ var Parser = function Parser(context, imports, fileInfo) {
1150
1138
  var index = parserInput.i;
1151
1139
  c = this.combinator();
1152
1140
  e = parserInput.$re(/^(?:\d+\.\d+|\d+)%/) ||
1141
+ // eslint-disable-next-line no-control-regex
1153
1142
  parserInput.$re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) ||
1154
1143
  parserInput.$char('*') || parserInput.$char('&') || this.attribute() ||
1155
- parserInput.$re(/^\([^&()@]+\)/) || parserInput.$re(/^[\.#:](?=@)/) ||
1144
+ parserInput.$re(/^\([^&()@]+\)/) || parserInput.$re(/^[.#:](?=@)/) ||
1156
1145
  this.entities.variableCurly();
1157
1146
  if (!e) {
1158
1147
  parserInput.save();
@@ -1170,7 +1159,7 @@ var Parser = function Parser(context, imports, fileInfo) {
1170
1159
  }
1171
1160
  }
1172
1161
  if (e) {
1173
- return new (tree_1.default.Element)(c, e, e instanceof tree_1.default.Variable, index, fileInfo);
1162
+ return new (tree_1.default.Element)(c, e, e instanceof tree_1.default.Variable, index + currentIndex, fileInfo);
1174
1163
  }
1175
1164
  },
1176
1165
  //
@@ -1263,7 +1252,7 @@ var Parser = function Parser(context, imports, fileInfo) {
1263
1252
  }
1264
1253
  }
1265
1254
  if (elements) {
1266
- return new (tree_1.default.Selector)(elements, allExtends, condition, index, fileInfo);
1255
+ return new (tree_1.default.Selector)(elements, allExtends, condition, index + currentIndex, fileInfo);
1267
1256
  }
1268
1257
  if (allExtends) {
1269
1258
  error('Extend must be used to extend a selector, it cannot be used on its own');
@@ -1285,13 +1274,13 @@ var Parser = function Parser(context, imports, fileInfo) {
1285
1274
  }
1286
1275
  parserInput.commentStore.length = 0;
1287
1276
  if (s.condition && selectors.length > 1) {
1288
- error("Guards are only currently allowed on a single selector.");
1277
+ error('Guards are only currently allowed on a single selector.');
1289
1278
  }
1290
1279
  if (!parserInput.$char(',')) {
1291
1280
  break;
1292
1281
  }
1293
1282
  if (s.condition) {
1294
- error("Guards are only currently allowed on a single selector.");
1283
+ error('Guards are only currently allowed on a single selector.');
1295
1284
  }
1296
1285
  parserInput.commentStore.length = 0;
1297
1286
  }
@@ -1311,7 +1300,7 @@ var Parser = function Parser(context, imports, fileInfo) {
1311
1300
  //
1312
1301
  var cif;
1313
1302
  if (!(key = entities.variableCurly())) {
1314
- key = expect(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/);
1303
+ key = expect(/^(?:[_A-Za-z0-9-*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/);
1315
1304
  }
1316
1305
  op = parserInput.$re(/^[|~*$^]?=/);
1317
1306
  if (op) {
@@ -1424,7 +1413,7 @@ var Parser = function Parser(context, imports, fileInfo) {
1424
1413
  merge = !isVariable && name.length > 1 && name.pop().value;
1425
1414
  // Custom property values get permissive parsing
1426
1415
  if (name[0].value && name[0].value.slice(0, 2) === '--') {
1427
- value = this.permissiveValue();
1416
+ value = this.permissiveValue(/[;}]/);
1428
1417
  }
1429
1418
  // Try to store values as anonymous
1430
1419
  // If we need the value later we'll re-parse it in ruleset.parseValue
@@ -1434,7 +1423,7 @@ var Parser = function Parser(context, imports, fileInfo) {
1434
1423
  if (value) {
1435
1424
  parserInput.forget();
1436
1425
  // anonymous values absorb the end ';' which is required for them to work
1437
- return new (tree_1.default.Declaration)(name, value, false, merge, index, fileInfo);
1426
+ return new (tree_1.default.Declaration)(name, value, false, merge, index + currentIndex, fileInfo);
1438
1427
  }
1439
1428
  if (!value) {
1440
1429
  value = this.value();
@@ -1449,7 +1438,7 @@ var Parser = function Parser(context, imports, fileInfo) {
1449
1438
  }
1450
1439
  if (value && (this.end() || hasDR)) {
1451
1440
  parserInput.forget();
1452
- return new (tree_1.default.Declaration)(name, value, important, merge, index, fileInfo);
1441
+ return new (tree_1.default.Declaration)(name, value, important, merge, index + currentIndex, fileInfo);
1453
1442
  }
1454
1443
  else {
1455
1444
  parserInput.restore();
@@ -1461,9 +1450,9 @@ var Parser = function Parser(context, imports, fileInfo) {
1461
1450
  },
1462
1451
  anonymousValue: function () {
1463
1452
  var index = parserInput.i;
1464
- var match = parserInput.$re(/^([^.#@\$+\/'"*`(;{}-]*);/);
1453
+ var match = parserInput.$re(/^([^.#@$+/'"*`(;{}-]*);/);
1465
1454
  if (match) {
1466
- return new (tree_1.default.Anonymous)(match[1], index);
1455
+ return new (tree_1.default.Anonymous)(match[1], index + currentIndex);
1467
1456
  }
1468
1457
  },
1469
1458
  /**
@@ -1572,13 +1561,13 @@ var Parser = function Parser(context, imports, fileInfo) {
1572
1561
  if (dir) {
1573
1562
  var options = (dir ? this.importOptions() : null) || {};
1574
1563
  if ((path = this.entities.quoted() || this.entities.url())) {
1575
- features = this.mediaFeatures();
1564
+ features = this.mediaFeatures({});
1576
1565
  if (!parserInput.$char(';')) {
1577
1566
  parserInput.i = index;
1578
1567
  error('missing semi-colon or unrecognised media features on import');
1579
1568
  }
1580
1569
  features = features && new (tree_1.default.Value)(features);
1581
- return new (tree_1.default.Import)(path, features, options, index, fileInfo);
1570
+ return new (tree_1.default.Import)(path, features, options, index + currentIndex, fileInfo);
1582
1571
  }
1583
1572
  else {
1584
1573
  parserInput.i = index;
@@ -1625,11 +1614,12 @@ var Parser = function Parser(context, imports, fileInfo) {
1625
1614
  return opt[1];
1626
1615
  }
1627
1616
  },
1628
- mediaFeature: function () {
1617
+ mediaFeature: function (syntaxOptions) {
1629
1618
  var entities = this.entities;
1630
1619
  var nodes = [];
1631
1620
  var e;
1632
1621
  var p;
1622
+ var rangeP;
1633
1623
  parserInput.save();
1634
1624
  do {
1635
1625
  e = entities.keyword() || entities.variable() || entities.mixinLookup();
@@ -1638,10 +1628,27 @@ var Parser = function Parser(context, imports, fileInfo) {
1638
1628
  }
1639
1629
  else if (parserInput.$char('(')) {
1640
1630
  p = this.property();
1641
- e = this.value();
1631
+ parserInput.save();
1632
+ if (!p && syntaxOptions.queryInParens && parserInput.$re(/^[0-9a-z-]*\s*([<>]=|<=|>=|[<>]|=)/)) {
1633
+ parserInput.restore();
1634
+ p = this.condition();
1635
+ parserInput.save();
1636
+ rangeP = this.atomicCondition(null, p.rvalue);
1637
+ if (!rangeP) {
1638
+ parserInput.restore();
1639
+ }
1640
+ }
1641
+ else {
1642
+ parserInput.restore();
1643
+ e = this.value();
1644
+ }
1642
1645
  if (parserInput.$char(')')) {
1643
- if (p && e) {
1644
- nodes.push(new (tree_1.default.Paren)(new (tree_1.default.Declaration)(p, e, null, null, parserInput.i, fileInfo, true)));
1646
+ if (p && !e) {
1647
+ nodes.push(new (tree_1.default.Paren)(new (tree_1.default.QueryInParens)(p.op, p.lvalue, p.rvalue, rangeP ? rangeP.op : null, rangeP ? rangeP.rvalue : null, p._index)));
1648
+ e = p;
1649
+ }
1650
+ else if (p && e) {
1651
+ nodes.push(new (tree_1.default.Paren)(new (tree_1.default.Declaration)(p, e, null, null, parserInput.i + currentIndex, fileInfo, true)));
1645
1652
  }
1646
1653
  else if (e) {
1647
1654
  nodes.push(new (tree_1.default.Paren)(e));
@@ -1660,12 +1667,12 @@ var Parser = function Parser(context, imports, fileInfo) {
1660
1667
  return new (tree_1.default.Expression)(nodes);
1661
1668
  }
1662
1669
  },
1663
- mediaFeatures: function () {
1670
+ mediaFeatures: function (syntaxOptions) {
1664
1671
  var entities = this.entities;
1665
1672
  var features = [];
1666
1673
  var e;
1667
1674
  do {
1668
- e = this.mediaFeature();
1675
+ e = this.mediaFeature(syntaxOptions);
1669
1676
  if (e) {
1670
1677
  features.push(e);
1671
1678
  if (!parserInput.$char(',')) {
@@ -1684,28 +1691,33 @@ var Parser = function Parser(context, imports, fileInfo) {
1684
1691
  } while (e);
1685
1692
  return features.length > 0 ? features : null;
1686
1693
  },
1687
- media: function () {
1688
- var features;
1689
- var rules;
1690
- var media;
1694
+ prepareAndGetNestableAtRule: function (treeType, index, debugInfo, syntaxOptions) {
1695
+ var features = this.mediaFeatures(syntaxOptions);
1696
+ var rules = this.block();
1697
+ if (!rules) {
1698
+ error('media definitions require block statements after any features');
1699
+ }
1700
+ parserInput.forget();
1701
+ var atRule = new (treeType)(rules, features, index + currentIndex, fileInfo);
1702
+ if (context.dumpLineNumbers) {
1703
+ atRule.debugInfo = debugInfo;
1704
+ }
1705
+ return atRule;
1706
+ },
1707
+ nestableAtRule: function () {
1691
1708
  var debugInfo;
1692
1709
  var index = parserInput.i;
1693
1710
  if (context.dumpLineNumbers) {
1694
1711
  debugInfo = getDebugInfo(index);
1695
1712
  }
1696
1713
  parserInput.save();
1697
- if (parserInput.$str('@media')) {
1698
- features = this.mediaFeatures();
1699
- rules = this.block();
1700
- if (!rules) {
1701
- error('media definitions require block statements after any features');
1714
+ if (parserInput.$peekChar('@')) {
1715
+ if (parserInput.$str('@media')) {
1716
+ return this.prepareAndGetNestableAtRule(tree_1.default.Media, index, debugInfo, atrule_syntax_1.MediaSyntaxOptions);
1702
1717
  }
1703
- parserInput.forget();
1704
- media = new (tree_1.default.Media)(rules, features, index, fileInfo);
1705
- if (context.dumpLineNumbers) {
1706
- media.debugInfo = debugInfo;
1718
+ if (parserInput.$str('@container')) {
1719
+ return this.prepareAndGetNestableAtRule(tree_1.default.Container, index, debugInfo, atrule_syntax_1.ContainerSyntaxOptions);
1707
1720
  }
1708
- return media;
1709
1721
  }
1710
1722
  parserInput.restore();
1711
1723
  },
@@ -1736,7 +1748,7 @@ var Parser = function Parser(context, imports, fileInfo) {
1736
1748
  parserInput.i = index;
1737
1749
  error('missing semi-colon on @plugin');
1738
1750
  }
1739
- return new (tree_1.default.Import)(path, null, options, index, fileInfo);
1751
+ return new (tree_1.default.Import)(path, null, options, index + currentIndex, fileInfo);
1740
1752
  }
1741
1753
  else {
1742
1754
  parserInput.i = index;
@@ -1751,7 +1763,7 @@ var Parser = function Parser(context, imports, fileInfo) {
1751
1763
  parserInput.restore();
1752
1764
  return null;
1753
1765
  }
1754
- var args = parserInput.$re(/^\s*([^\);]+)\)\s*/);
1766
+ var args = parserInput.$re(/^\s*([^);]+)\)\s*/);
1755
1767
  if (args[1]) {
1756
1768
  parserInput.forget();
1757
1769
  return args[1].trim();
@@ -1780,7 +1792,7 @@ var Parser = function Parser(context, imports, fileInfo) {
1780
1792
  if (parserInput.currentChar() !== '@') {
1781
1793
  return;
1782
1794
  }
1783
- value = this['import']() || this.plugin() || this.media();
1795
+ value = this['import']() || this.plugin() || this.nestableAtRule();
1784
1796
  if (value) {
1785
1797
  return value;
1786
1798
  }
@@ -1845,7 +1857,7 @@ var Parser = function Parser(context, imports, fileInfo) {
1845
1857
  }
1846
1858
  if (rules || (!hasBlock && value && parserInput.$char(';'))) {
1847
1859
  parserInput.forget();
1848
- return new (tree_1.default.AtRule)(name, value, rules, index, fileInfo, context.dumpLineNumbers ? getDebugInfo(index) : null, isRooted);
1860
+ return new (tree_1.default.AtRule)(name, value, rules, index + currentIndex, fileInfo, context.dumpLineNumbers ? getDebugInfo(index) : null, isRooted);
1849
1861
  }
1850
1862
  parserInput.restore('at-rule options not recognised');
1851
1863
  },
@@ -1871,7 +1883,7 @@ var Parser = function Parser(context, imports, fileInfo) {
1871
1883
  }
1872
1884
  } while (e);
1873
1885
  if (expressions.length > 0) {
1874
- return new (tree_1.default.Value)(expressions, index);
1886
+ return new (tree_1.default.Value)(expressions, index + currentIndex);
1875
1887
  }
1876
1888
  },
1877
1889
  important: function () {
@@ -1906,7 +1918,7 @@ var Parser = function Parser(context, imports, fileInfo) {
1906
1918
  if (m) {
1907
1919
  isSpaced = parserInput.isWhitespace(-1);
1908
1920
  while (true) {
1909
- if (parserInput.peek(/^\/[*\/]/)) {
1921
+ if (parserInput.peek(/^\/[*/]/)) {
1910
1922
  break;
1911
1923
  }
1912
1924
  parserInput.save();
@@ -1970,7 +1982,7 @@ var Parser = function Parser(context, imports, fileInfo) {
1970
1982
  if (!b) {
1971
1983
  break;
1972
1984
  }
1973
- condition = new (tree_1.default.Condition)('or', condition || a, b, index);
1985
+ condition = new (tree_1.default.Condition)('or', condition || a, b, index + currentIndex);
1974
1986
  }
1975
1987
  return condition || a;
1976
1988
  }
@@ -2077,18 +2089,22 @@ var Parser = function Parser(context, imports, fileInfo) {
2077
2089
  parserInput.forget();
2078
2090
  return body;
2079
2091
  },
2080
- atomicCondition: function (needsParens) {
2092
+ atomicCondition: function (needsParens, preparsedCond) {
2081
2093
  var entities = this.entities;
2082
2094
  var index = parserInput.i;
2083
2095
  var a;
2084
2096
  var b;
2085
2097
  var c;
2086
2098
  var op;
2087
- function cond() {
2099
+ var cond = (function () {
2088
2100
  return this.addition() || entities.keyword() || entities.quoted() || entities.mixinLookup();
2101
+ }).bind(this);
2102
+ if (preparsedCond) {
2103
+ a = preparsedCond;
2104
+ }
2105
+ else {
2106
+ a = cond();
2089
2107
  }
2090
- cond = cond.bind(this);
2091
- a = cond();
2092
2108
  if (a) {
2093
2109
  if (parserInput.$char('>')) {
2094
2110
  if (parserInput.$char('=')) {
@@ -2120,14 +2136,14 @@ var Parser = function Parser(context, imports, fileInfo) {
2120
2136
  if (op) {
2121
2137
  b = cond();
2122
2138
  if (b) {
2123
- c = new (tree_1.default.Condition)(op, a, b, index, false);
2139
+ c = new (tree_1.default.Condition)(op, a, b, index + currentIndex, false);
2124
2140
  }
2125
2141
  else {
2126
2142
  error('expected expression');
2127
2143
  }
2128
2144
  }
2129
- else {
2130
- c = new (tree_1.default.Condition)('=', a, new (tree_1.default.Keyword)('true'), index, false);
2145
+ else if (!preparsedCond) {
2146
+ c = new (tree_1.default.Condition)('=', a, new (tree_1.default.Keyword)('true'), index + currentIndex, false);
2131
2147
  }
2132
2148
  return c;
2133
2149
  }
@@ -2139,7 +2155,7 @@ var Parser = function Parser(context, imports, fileInfo) {
2139
2155
  operand: function () {
2140
2156
  var entities = this.entities;
2141
2157
  var negate;
2142
- if (parserInput.peek(/^-[@\$\(]/)) {
2158
+ if (parserInput.peek(/^-[@$(]/)) {
2143
2159
  negate = parserInput.$char('-');
2144
2160
  }
2145
2161
  var o = this.sub() || entities.dimension() ||
@@ -2178,10 +2194,10 @@ var Parser = function Parser(context, imports, fileInfo) {
2178
2194
  if (e) {
2179
2195
  entities.push(e);
2180
2196
  // operations do not allow keyword "/" dimension (e.g. small/20px) so we support that here
2181
- if (!parserInput.peek(/^\/[\/*]/)) {
2197
+ if (!parserInput.peek(/^\/[/*]/)) {
2182
2198
  delim = parserInput.$char('/');
2183
2199
  if (delim) {
2184
- entities.push(new (tree_1.default.Anonymous)(delim, index));
2200
+ entities.push(new (tree_1.default.Anonymous)(delim, index + currentIndex));
2185
2201
  }
2186
2202
  }
2187
2203
  }
@@ -2218,7 +2234,7 @@ var Parser = function Parser(context, imports, fileInfo) {
2218
2234
  }
2219
2235
  match(/^(\*?)/);
2220
2236
  while (true) {
2221
- if (!match(/^((?:[\w-]+)|(?:[@\$]\{[\w-]+\}))/)) {
2237
+ if (!match(/^((?:[\w-]+)|(?:[@$]\{[\w-]+\}))/)) {
2222
2238
  break;
2223
2239
  }
2224
2240
  }
@@ -2235,8 +2251,8 @@ var Parser = function Parser(context, imports, fileInfo) {
2235
2251
  name[k] = (s.charAt(0) !== '@' && s.charAt(0) !== '$') ?
2236
2252
  new (tree_1.default.Keyword)(s) :
2237
2253
  (s.charAt(0) === '@' ?
2238
- new (tree_1.default.Variable)("@" + s.slice(2, -1), index[k], fileInfo) :
2239
- new (tree_1.default.Property)("$" + s.slice(2, -1), index[k], fileInfo));
2254
+ new (tree_1.default.Variable)("@" + s.slice(2, -1), index[k] + currentIndex, fileInfo) :
2255
+ new (tree_1.default.Property)("$" + s.slice(2, -1), index[k] + currentIndex, fileInfo));
2240
2256
  }
2241
2257
  return name;
2242
2258
  }