less 4.9.1 → 5.0.0-alpha.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 (134) hide show
  1. package/README.md +23 -5
  2. package/V5-STATUS.md +71 -0
  3. package/bin/lessc +302 -626
  4. package/dist/less-browser-dev.js +2550 -0
  5. package/dist/less-node.cjs +480 -14561
  6. package/index.cjs +5 -2
  7. package/lib/browser-dev.js +86 -0
  8. package/lib/index.js +164 -0
  9. package/lib/lessc-helper.js +64 -0
  10. package/lib/logger.js +76 -0
  11. package/lib/options.d.ts +82 -0
  12. package/lib/options.js +227 -0
  13. package/lib/types.js +20 -0
  14. package/lib/version.js +19 -0
  15. package/package.json +36 -40
  16. package/dist/less.cjs +0 -15218
  17. package/dist/less.js +0 -15218
  18. package/dist/less.min.js +0 -11
  19. package/dist/less.min.js.map +0 -1
  20. package/lib/less/constants.js +0 -13
  21. package/lib/less/contexts.js +0 -165
  22. package/lib/less/data/colors.js +0 -150
  23. package/lib/less/data/index.js +0 -4
  24. package/lib/less/data/unit-conversions.js +0 -21
  25. package/lib/less/default-options.js +0 -89
  26. package/lib/less/deprecation.js +0 -82
  27. package/lib/less/environment/abstract-file-manager.js +0 -140
  28. package/lib/less/environment/abstract-plugin-loader.js +0 -185
  29. package/lib/less/environment/environment-api.ts +0 -21
  30. package/lib/less/environment/environment.js +0 -59
  31. package/lib/less/environment/file-manager-api.ts +0 -77
  32. package/lib/less/functions/boolean.js +0 -29
  33. package/lib/less/functions/color-blending.js +0 -85
  34. package/lib/less/functions/color.js +0 -452
  35. package/lib/less/functions/data-uri.js +0 -74
  36. package/lib/less/functions/default.js +0 -26
  37. package/lib/less/functions/function-caller.js +0 -55
  38. package/lib/less/functions/function-registry.js +0 -36
  39. package/lib/less/functions/index.js +0 -35
  40. package/lib/less/functions/list.js +0 -158
  41. package/lib/less/functions/math-helper.js +0 -22
  42. package/lib/less/functions/math.js +0 -30
  43. package/lib/less/functions/number.js +0 -95
  44. package/lib/less/functions/string.js +0 -39
  45. package/lib/less/functions/style.js +0 -29
  46. package/lib/less/functions/svg.js +0 -87
  47. package/lib/less/functions/types.js +0 -70
  48. package/lib/less/import-manager.js +0 -183
  49. package/lib/less/index.js +0 -95
  50. package/lib/less/less-error.js +0 -166
  51. package/lib/less/logger.js +0 -34
  52. package/lib/less/parse-tree.js +0 -124
  53. package/lib/less/parse.js +0 -87
  54. package/lib/less/parser/lookup-pattern.js +0 -26
  55. package/lib/less/parser/parser-input.js +0 -400
  56. package/lib/less/parser/parser.js +0 -2998
  57. package/lib/less/plugin-manager.js +0 -168
  58. package/lib/less/render.js +0 -41
  59. package/lib/less/source-map-builder.js +0 -82
  60. package/lib/less/source-map-output.js +0 -151
  61. package/lib/less/transform-tree.js +0 -102
  62. package/lib/less/tree/anonymous.js +0 -61
  63. package/lib/less/tree/assignment.js +0 -48
  64. package/lib/less/tree/atrule-syntax.js +0 -8
  65. package/lib/less/tree/atrule.js +0 -340
  66. package/lib/less/tree/attribute.js +0 -63
  67. package/lib/less/tree/call.js +0 -132
  68. package/lib/less/tree/color.js +0 -285
  69. package/lib/less/tree/combinator.js +0 -38
  70. package/lib/less/tree/comment.js +0 -48
  71. package/lib/less/tree/condition.js +0 -65
  72. package/lib/less/tree/container.js +0 -104
  73. package/lib/less/tree/debug-info.js +0 -80
  74. package/lib/less/tree/declaration.js +0 -142
  75. package/lib/less/tree/detached-ruleset.js +0 -45
  76. package/lib/less/tree/dimension.js +0 -215
  77. package/lib/less/tree/element.js +0 -93
  78. package/lib/less/tree/expression.js +0 -100
  79. package/lib/less/tree/extend.js +0 -88
  80. package/lib/less/tree/import.js +0 -299
  81. package/lib/less/tree/index.js +0 -56
  82. package/lib/less/tree/interpolated-variable.js +0 -106
  83. package/lib/less/tree/javascript.js +0 -45
  84. package/lib/less/tree/js-eval-node.js +0 -80
  85. package/lib/less/tree/keyword.js +0 -28
  86. package/lib/less/tree/media.js +0 -90
  87. package/lib/less/tree/merge-rules.js +0 -47
  88. package/lib/less/tree/mixin-call.js +0 -283
  89. package/lib/less/tree/mixin-definition.js +0 -319
  90. package/lib/less/tree/namespace-value.js +0 -95
  91. package/lib/less/tree/negative.js +0 -37
  92. package/lib/less/tree/nested-at-rule.js +0 -239
  93. package/lib/less/tree/node.js +0 -310
  94. package/lib/less/tree/operation.js +0 -81
  95. package/lib/less/tree/paren.js +0 -41
  96. package/lib/less/tree/property.js +0 -96
  97. package/lib/less/tree/query-in-parens.js +0 -64
  98. package/lib/less/tree/quoted.js +0 -131
  99. package/lib/less/tree/ruleset.js +0 -1068
  100. package/lib/less/tree/selector.js +0 -201
  101. package/lib/less/tree/unicode-descriptor.js +0 -14
  102. package/lib/less/tree/unit.js +0 -170
  103. package/lib/less/tree/url.js +0 -83
  104. package/lib/less/tree/value.js +0 -60
  105. package/lib/less/tree/variable-call.js +0 -60
  106. package/lib/less/tree/variable.js +0 -85
  107. package/lib/less/utils.js +0 -126
  108. package/lib/less/visitors/extend-visitor.js +0 -505
  109. package/lib/less/visitors/import-sequencer.js +0 -56
  110. package/lib/less/visitors/import-visitor.js +0 -203
  111. package/lib/less/visitors/index.js +0 -15
  112. package/lib/less/visitors/join-selector-visitor.js +0 -65
  113. package/lib/less/visitors/set-tree-visibility-visitor.js +0 -57
  114. package/lib/less/visitors/to-css-visitor.js +0 -332
  115. package/lib/less/visitors/visitor.js +0 -165
  116. package/lib/less-browser/add-default-options.js +0 -53
  117. package/lib/less-browser/bootstrap.js +0 -67
  118. package/lib/less-browser/browser.js +0 -65
  119. package/lib/less-browser/cache.js +0 -43
  120. package/lib/less-browser/error-reporting.js +0 -170
  121. package/lib/less-browser/file-manager.js +0 -112
  122. package/lib/less-browser/image-size.js +0 -28
  123. package/lib/less-browser/index.js +0 -284
  124. package/lib/less-browser/log-listener.js +0 -42
  125. package/lib/less-browser/plugin-loader.js +0 -24
  126. package/lib/less-browser/utils.js +0 -30
  127. package/lib/less-node/environment.js +0 -43
  128. package/lib/less-node/file-manager.js +0 -156
  129. package/lib/less-node/fs.js +0 -14
  130. package/lib/less-node/image-size.js +0 -78
  131. package/lib/less-node/index.js +0 -31
  132. package/lib/less-node/lessc-helper.js +0 -95
  133. package/lib/less-node/plugin-loader.js +0 -62
  134. package/lib/less-node/url-file-manager.js +0 -60
@@ -1,142 +0,0 @@
1
- // @ts-check
2
- /** @import { EvalContext, CSSOutput, FileInfo } from './node.js' */
3
- import Node from './node.js';
4
- import Value from './value.js';
5
- import Keyword from './keyword.js';
6
- import Anonymous from './anonymous.js';
7
- import * as Constants from '../constants.js';
8
- const MATH = Constants.Math;
9
-
10
- /**
11
- * @param {EvalContext} context
12
- * @param {Node[]} name
13
- * @returns {string}
14
- */
15
- function evalName(context, name) {
16
- let value = '';
17
- let i;
18
- const n = name.length;
19
- /** @type {CSSOutput} */
20
- const output = {add: function (s) {value += s;}, isEmpty: function() { return value === ''; }};
21
- for (i = 0; i < n; i++) {
22
- name[i].eval(context).genCSS(context, output);
23
- }
24
- return value;
25
- }
26
-
27
- class Declaration extends Node {
28
- get type() { return 'Declaration'; }
29
-
30
- /**
31
- * @param {string | Node[]} name
32
- * @param {Node | string | null} value
33
- * @param {string} [important]
34
- * @param {string} [merge]
35
- * @param {number} [index]
36
- * @param {FileInfo} [currentFileInfo]
37
- * @param {boolean} [inline]
38
- * @param {boolean} [variable]
39
- */
40
- constructor(name, value, important, merge, index, currentFileInfo, inline, variable) {
41
- super();
42
- this.name = name;
43
- this.value = (value instanceof Node) ? value : new Value([value ? new Anonymous(value) : null]);
44
- this.important = important ? ` ${important.trim()}` : '';
45
- /** @type {string | undefined} */
46
- this.merge = merge;
47
- this._index = index;
48
- this._fileInfo = currentFileInfo;
49
- /** @type {boolean} */
50
- this.inline = inline || false;
51
- /** @type {boolean} */
52
- this.variable = (variable !== undefined) ? variable
53
- : (typeof name === 'string' && name.charAt(0) === '@');
54
- /** @type {boolean} */
55
- this.allowRoot = true;
56
- this.setParent(this.value, this);
57
- }
58
-
59
- /**
60
- * @param {EvalContext} context
61
- * @param {CSSOutput} output
62
- */
63
- genCSS(context, output) {
64
- output.add(/** @type {string} */ (this.name) + (context.compress ? ':' : ': '), this.fileInfo(), this.getIndex());
65
- try {
66
- /** @type {Node} */ (this.value).genCSS(context, output);
67
- }
68
- catch (e) {
69
- const err = /** @type {{ index?: number, filename?: string }} */ (e);
70
- err.index = this._index;
71
- err.filename = this._fileInfo && this._fileInfo.filename;
72
- throw e;
73
- }
74
- output.add(this.important + ((this.inline || (context.lastRule && context.compress)) ? '' : ';'), this._fileInfo, this._index);
75
- }
76
-
77
- /** @param {EvalContext} context */
78
- eval(context) {
79
- let mathBypass = false, prevMath, name = this.name, evaldValue, variable = this.variable;
80
- if (typeof name !== 'string') {
81
- // expand 'primitive' name directly to get
82
- // things faster (~10% for benchmark.less):
83
- name = (/** @type {Node[]} */ (name).length === 1) && (/** @type {Node[]} */ (name)[0] instanceof Keyword) ?
84
- /** @type {string} */ (/** @type {Node[]} */ (name)[0].value) : evalName(context, /** @type {Node[]} */ (name));
85
- variable = false; // never treat expanded interpolation as new variable name
86
- }
87
-
88
- // @todo remove when parens-division is default
89
- if (name === 'font' && context.math === MATH.ALWAYS) {
90
- mathBypass = true;
91
- prevMath = context.math;
92
- context.math = MATH.PARENS_DIVISION;
93
- }
94
- try {
95
- context.importantScope.push({});
96
- evaldValue = /** @type {Node} */ (this.value).eval(context);
97
-
98
- // A mixin call used as a property value (without a lookup) evaluates
99
- // to its ruleset, which arrives here as an array of rules; without
100
- // this guard it renders as `[object Object]`.
101
- if (!this.variable && (evaldValue.type === 'DetachedRuleset' || Array.isArray(evaldValue))) {
102
- throw { message: 'Rulesets cannot be evaluated on a property.',
103
- index: this.getIndex(), filename: this.fileInfo().filename };
104
- }
105
- let important = this.important;
106
- const importantResult = context.importantScope.pop();
107
- if (!important && importantResult && importantResult.important) {
108
- important = importantResult.important;
109
- }
110
-
111
- return new Declaration(/** @type {string} */ (name),
112
- evaldValue,
113
- important,
114
- this.merge,
115
- this.getIndex(), this.fileInfo(), this.inline,
116
- variable);
117
- }
118
- catch (e) {
119
- const err = /** @type {{ index?: number, filename?: string }} */ (e);
120
- if (typeof err.index !== 'number') {
121
- err.index = this.getIndex();
122
- err.filename = this.fileInfo().filename;
123
- }
124
- throw e;
125
- }
126
- finally {
127
- if (mathBypass) {
128
- context.math = prevMath;
129
- }
130
- }
131
- }
132
-
133
- makeImportant() {
134
- return new Declaration(this.name,
135
- /** @type {Node} */ (this.value),
136
- '!important',
137
- this.merge,
138
- this.getIndex(), this.fileInfo(), this.inline);
139
- }
140
- }
141
-
142
- export default Declaration;
@@ -1,45 +0,0 @@
1
- // @ts-check
2
- /** @import { EvalContext, TreeVisitor } from './node.js' */
3
- import Node from './node.js';
4
- import contexts from '../contexts.js';
5
- import * as utils from '../utils.js';
6
-
7
- class DetachedRuleset extends Node {
8
- get type() { return 'DetachedRuleset'; }
9
-
10
- /**
11
- * @param {Node} ruleset
12
- * @param {Node[]} [frames]
13
- */
14
- constructor(ruleset, frames) {
15
- super();
16
- this.ruleset = ruleset;
17
- this.frames = frames;
18
- this.evalFirst = true;
19
- this.setParent(this.ruleset, this);
20
- }
21
-
22
- /** @param {TreeVisitor} visitor */
23
- accept(visitor) {
24
- this.ruleset = visitor.visit(this.ruleset);
25
- }
26
-
27
- /**
28
- * @param {EvalContext} context
29
- * @returns {DetachedRuleset}
30
- */
31
- eval(context) {
32
- const frames = this.frames || utils.copyArray(context.frames);
33
- return new DetachedRuleset(this.ruleset, frames);
34
- }
35
-
36
- /**
37
- * @param {EvalContext} context
38
- * @returns {Node}
39
- */
40
- callEval(context) {
41
- return this.ruleset.eval(this.frames ? new contexts.Eval(context, this.frames.concat(context.frames)) : context);
42
- }
43
- }
44
-
45
- export default DetachedRuleset;
@@ -1,215 +0,0 @@
1
- // @ts-check
2
- /* eslint-disable no-prototype-builtins */
3
- import Node from './node.js';
4
- import unitConversions from '../data/unit-conversions.js';
5
- import Unit from './unit.js';
6
- import Color from './color.js';
7
-
8
- /** @import { EvalContext, CSSOutput } from './node.js' */
9
-
10
- //
11
- // A number with a unit
12
- //
13
- class Dimension extends Node {
14
- get type() { return 'Dimension'; }
15
-
16
- /**
17
- * @param {number | string} value
18
- * @param {Unit | string} [unit]
19
- */
20
- constructor(value, unit) {
21
- super();
22
- /** @type {number} */
23
- this.value = parseFloat(/** @type {string} */ (value));
24
- if (isNaN(this.value)) {
25
- throw new Error('Dimension is not a number.');
26
- }
27
- /** @type {Unit} */
28
- this.unit = (unit && unit instanceof Unit) ? unit :
29
- new Unit(unit ? [/** @type {string} */ (unit)] : undefined);
30
- this.setParent(this.unit, this);
31
- }
32
-
33
- /**
34
- * @param {import('./node.js').TreeVisitor} visitor
35
- */
36
- accept(visitor) {
37
- this.unit = /** @type {Unit} */ (visitor.visit(this.unit));
38
- }
39
-
40
- // remove when Nodes have JSDoc types
41
- // eslint-disable-next-line no-unused-vars
42
- /** @param {EvalContext} context */
43
- eval(context) {
44
- return this;
45
- }
46
-
47
- toColor() {
48
- const v = /** @type {number} */ (this.value);
49
- return new Color([v, v, v]);
50
- }
51
-
52
- /**
53
- * @param {EvalContext} context
54
- * @param {CSSOutput} output
55
- */
56
- genCSS(context, output) {
57
- if ((context && context.strictUnits) && !this.unit.isSingular()) {
58
- throw new Error(`Multiple units in dimension. Correct the units or use the unit function. Bad unit: ${this.unit.toString()}`);
59
- }
60
-
61
- const value = this.fround(context, /** @type {number} */ (this.value));
62
- let strValue = String(value);
63
-
64
- if (value !== 0 && value < 0.000001 && value > -0.000001) {
65
- // would be output 1e-6 etc.
66
- strValue = value.toFixed(20).replace(/0+$/, '');
67
- }
68
-
69
- if (context && context.compress) {
70
- // Zero values doesn't need a unit
71
- if (value === 0 && this.unit.isLength()) {
72
- output.add(strValue);
73
- return;
74
- }
75
-
76
- // Float values doesn't need a leading zero
77
- if (value > 0 && value < 1) {
78
- strValue = (strValue).slice(1);
79
- }
80
- }
81
-
82
- output.add(strValue);
83
- this.unit.genCSS(context, output);
84
- }
85
-
86
- // In an operation between two Dimensions,
87
- // we default to the first Dimension's unit,
88
- // so `1px + 2` will yield `3px`.
89
- /**
90
- * @param {EvalContext} context
91
- * @param {string} op
92
- * @param {Dimension} other
93
- */
94
- operate(context, op, other) {
95
- /* jshint noempty:false */
96
- let value = this._operate(context, op, /** @type {number} */ (this.value), /** @type {number} */ (other.value));
97
- let unit = this.unit.clone();
98
-
99
- if (op === '+' || op === '-') {
100
- if (unit.numerator.length === 0 && unit.denominator.length === 0) {
101
- unit = other.unit.clone();
102
- if (this.unit.backupUnit) {
103
- unit.backupUnit = this.unit.backupUnit;
104
- }
105
- } else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) {
106
- // do nothing
107
- } else {
108
- other = other.convertTo(this.unit.usedUnits());
109
-
110
- if (context.strictUnits && other.unit.toString() !== unit.toString()) {
111
- throw new Error('Incompatible units. Change the units or use the unit function. '
112
- + `Bad units: '${unit.toString()}' and '${other.unit.toString()}'.`);
113
- }
114
-
115
- value = this._operate(context, op, /** @type {number} */ (this.value), /** @type {number} */ (other.value));
116
- }
117
- } else if (op === '*') {
118
- unit.numerator = unit.numerator.concat(other.unit.numerator).sort();
119
- unit.denominator = unit.denominator.concat(other.unit.denominator).sort();
120
- unit.cancel();
121
- } else if (op === '/') {
122
- unit.numerator = unit.numerator.concat(other.unit.denominator).sort();
123
- unit.denominator = unit.denominator.concat(other.unit.numerator).sort();
124
- unit.cancel();
125
- }
126
- return new Dimension(/** @type {number} */ (value), unit);
127
- }
128
-
129
- /**
130
- * @param {Node} other
131
- * @returns {number | undefined}
132
- */
133
- compare(other) {
134
- let a, b;
135
-
136
- if (!(other instanceof Dimension)) {
137
- return undefined;
138
- }
139
-
140
- if (this.unit.isEmpty() || other.unit.isEmpty()) {
141
- a = this;
142
- b = other;
143
- } else {
144
- a = this.unify();
145
- b = other.unify();
146
- if (a.unit.compare(b.unit) !== 0) {
147
- return undefined;
148
- }
149
- }
150
-
151
- return Node.numericCompare(/** @type {number} */ (a.value), /** @type {number} */ (b.value));
152
- }
153
-
154
- unify() {
155
- return this.convertTo({ length: 'px', duration: 's', angle: 'rad' });
156
- }
157
-
158
- /**
159
- * @param {string | { [groupName: string]: string }} conversions
160
- * @returns {Dimension}
161
- */
162
- convertTo(conversions) {
163
- let value = /** @type {number} */ (this.value);
164
- const unit = this.unit.clone();
165
- let i;
166
- /** @type {string} */
167
- let groupName;
168
- /** @type {{ [unitName: string]: number }} */
169
- let group;
170
- /** @type {string} */
171
- let targetUnit;
172
- /** @type {{ [groupName: string]: string }} */
173
- let derivedConversions = {};
174
- /** @type {(atomicUnit: string, denominator: boolean) => string} */
175
- let applyUnit;
176
-
177
- if (typeof conversions === 'string') {
178
- for (i in unitConversions) {
179
- if (unitConversions[/** @type {keyof typeof unitConversions} */ (i)].hasOwnProperty(conversions)) {
180
- derivedConversions = {};
181
- derivedConversions[i] = conversions;
182
- }
183
- }
184
- conversions = derivedConversions;
185
- }
186
- applyUnit = function (atomicUnit, denominator) {
187
- if (group.hasOwnProperty(atomicUnit)) {
188
- if (denominator) {
189
- value = value / (group[atomicUnit] / group[targetUnit]);
190
- } else {
191
- value = value * (group[atomicUnit] / group[targetUnit]);
192
- }
193
-
194
- return targetUnit;
195
- }
196
-
197
- return atomicUnit;
198
- };
199
-
200
- for (groupName in conversions) {
201
- if (conversions.hasOwnProperty(groupName)) {
202
- targetUnit = conversions[groupName];
203
- group = /** @type {{ [unitName: string]: number }} */ (unitConversions[/** @type {keyof typeof unitConversions} */ (groupName)]);
204
-
205
- unit.map(applyUnit);
206
- }
207
- }
208
-
209
- unit.cancel();
210
-
211
- return new Dimension(value, unit);
212
- }
213
- }
214
-
215
- export default Dimension;
@@ -1,93 +0,0 @@
1
- // @ts-check
2
- /** @import { EvalContext, CSSOutput, TreeVisitor, FileInfo, VisibilityInfo } from './node.js' */
3
- import Node from './node.js';
4
- import Paren from './paren.js';
5
- import Combinator from './combinator.js';
6
-
7
- class Element extends Node {
8
- get type() { return 'Element'; }
9
-
10
- /**
11
- * @param {Combinator | string} combinator
12
- * @param {string | Node} value
13
- * @param {boolean} [isVariable]
14
- * @param {number} [index]
15
- * @param {FileInfo} [currentFileInfo]
16
- * @param {VisibilityInfo} [visibilityInfo]
17
- */
18
- constructor(combinator, value, isVariable, index, currentFileInfo, visibilityInfo) {
19
- super();
20
- this.combinator = combinator instanceof Combinator ?
21
- combinator : new Combinator(combinator);
22
-
23
- if (typeof value === 'string') {
24
- this.value = value.trim();
25
- } else if (value) {
26
- this.value = value;
27
- } else {
28
- this.value = '';
29
- }
30
- /** @type {boolean | undefined} */
31
- this.isVariable = isVariable;
32
- this._index = index;
33
- this._fileInfo = currentFileInfo;
34
- this.copyVisibilityInfo(visibilityInfo);
35
- this.setParent(this.combinator, this);
36
- }
37
-
38
- /** @param {TreeVisitor} visitor */
39
- accept(visitor) {
40
- const value = this.value;
41
- this.combinator = /** @type {Combinator} */ (visitor.visit(this.combinator));
42
- if (typeof value === 'object') {
43
- this.value = visitor.visit(/** @type {Node} */ (value));
44
- }
45
- }
46
-
47
- /** @param {EvalContext} context */
48
- eval(context) {
49
- return new Element(this.combinator,
50
- /** @type {Node} */ (this.value).eval ? /** @type {Node} */ (this.value).eval(context) : /** @type {string} */ (this.value),
51
- this.isVariable,
52
- this.getIndex(),
53
- this.fileInfo(), this.visibilityInfo());
54
- }
55
-
56
- clone() {
57
- return new Element(this.combinator,
58
- /** @type {string | Node} */ (this.value),
59
- this.isVariable,
60
- this.getIndex(),
61
- this.fileInfo(), this.visibilityInfo());
62
- }
63
-
64
- /**
65
- * @param {EvalContext} context
66
- * @param {CSSOutput} output
67
- */
68
- genCSS(context, output) {
69
- output.add(this.toCSS(context), this.fileInfo(), this.getIndex());
70
- }
71
-
72
- /** @param {EvalContext} [context] */
73
- toCSS(context) {
74
- /** @type {EvalContext & { firstSelector?: boolean }} */
75
- const ctx = context || {};
76
- let value = this.value;
77
- const firstSelector = ctx.firstSelector;
78
- if (value instanceof Paren) {
79
- // selector in parens should not be affected by outer selector
80
- // flags (breaks only interpolated selectors - see #1973)
81
- ctx.firstSelector = true;
82
- }
83
- value = /** @type {Node} */ (value).toCSS ? /** @type {Node} */ (value).toCSS(ctx) : /** @type {string} */ (value);
84
- ctx.firstSelector = firstSelector;
85
- if (value === '' && this.combinator.value.charAt(0) === '&') {
86
- return '';
87
- } else {
88
- return this.combinator.toCSS(ctx) + value;
89
- }
90
- }
91
- }
92
-
93
- export default Element;
@@ -1,100 +0,0 @@
1
- // @ts-check
2
- /** @import { EvalContext, CSSOutput, TreeVisitor } from './node.js' */
3
- import Node from './node.js';
4
- import Paren from './paren.js';
5
- import Comment from './comment.js';
6
- import Dimension from './dimension.js';
7
- import Anonymous from './anonymous.js';
8
-
9
- class Expression extends Node {
10
- get type() { return 'Expression'; }
11
-
12
- /**
13
- * @param {Node[]} value
14
- * @param {boolean} [noSpacing]
15
- */
16
- constructor(value, noSpacing) {
17
- super();
18
- this.value = value;
19
- /** @type {boolean | undefined} */
20
- this.noSpacing = noSpacing;
21
- /** @type {boolean | undefined} */
22
- this.parens = undefined;
23
- /** @type {boolean | undefined} */
24
- this.parensInOp = undefined;
25
- if (!value) {
26
- throw new Error('Expression requires an array parameter');
27
- }
28
- }
29
-
30
- /** @param {TreeVisitor} visitor */
31
- accept(visitor) {
32
- this.value = visitor.visitArray(/** @type {Node[]} */ (this.value));
33
- }
34
-
35
- /** @param {EvalContext} context */
36
- eval(context) {
37
- const noSpacing = this.noSpacing;
38
- /** @type {Node | Expression} */
39
- let returnValue;
40
- const mathOn = context.isMathOn();
41
- const inParenthesis = this.parens;
42
-
43
- let doubleParen = false;
44
- if (inParenthesis) {
45
- context.inParenthesis();
46
- }
47
- const value = /** @type {Node[]} */ (this.value);
48
- if (value.length > 1) {
49
- returnValue = new Expression(value.map(function (e) {
50
- if (!e.eval) {
51
- return e;
52
- }
53
- return e.eval(context);
54
- }), this.noSpacing);
55
- } else if (value.length === 1) {
56
- const first = /** @type {Expression} */ (value[0]);
57
- if (first.parens && !first.parensInOp && !context.inCalc) {
58
- doubleParen = true;
59
- }
60
- returnValue = value[0].eval(context);
61
- } else {
62
- returnValue = this;
63
- }
64
- if (inParenthesis) {
65
- context.outOfParenthesis();
66
- }
67
- if (this.parens && this.parensInOp && !mathOn && !doubleParen
68
- && (!(returnValue instanceof Dimension))) {
69
- returnValue = new Paren(returnValue);
70
- }
71
- /** @type {Expression} */ (returnValue).noSpacing =
72
- /** @type {Expression} */ (returnValue).noSpacing || noSpacing;
73
- return returnValue;
74
- }
75
-
76
- /**
77
- * @param {EvalContext} context
78
- * @param {CSSOutput} output
79
- */
80
- genCSS(context, output) {
81
- const value = /** @type {Node[]} */ (this.value);
82
- for (let i = 0; i < value.length; i++) {
83
- value[i].genCSS(context, output);
84
- if (!this.noSpacing && i + 1 < value.length) {
85
- if (!(value[i + 1] instanceof Anonymous) ||
86
- value[i + 1] instanceof Anonymous && /** @type {string} */ (value[i + 1].value) !== ',') {
87
- output.add(' ');
88
- }
89
- }
90
- }
91
- }
92
-
93
- throwAwayComments() {
94
- this.value = /** @type {Node[]} */ (this.value).filter(function(v) {
95
- return !(v instanceof Comment);
96
- });
97
- }
98
- }
99
-
100
- export default Expression;
@@ -1,88 +0,0 @@
1
- // @ts-check
2
- /** @import { EvalContext, TreeVisitor, FileInfo, VisibilityInfo } from './node.js' */
3
- import Node from './node.js';
4
- import Selector from './selector.js';
5
-
6
- class Extend extends Node {
7
- get type() { return 'Extend'; }
8
-
9
- /**
10
- * @param {Selector} selector
11
- * @param {string} option
12
- * @param {number} index
13
- * @param {FileInfo} currentFileInfo
14
- * @param {VisibilityInfo} [visibilityInfo]
15
- */
16
- constructor(selector, option, index, currentFileInfo, visibilityInfo) {
17
- super();
18
- this.selector = selector;
19
- this.option = option;
20
- this.object_id = Extend.next_id++;
21
- /** @type {number[]} */
22
- this.parent_ids = [this.object_id];
23
- this._index = index;
24
- this._fileInfo = currentFileInfo;
25
- this.copyVisibilityInfo(visibilityInfo);
26
- /** @type {boolean} */
27
- this.allowRoot = true;
28
- /** @type {boolean} */
29
- this.allowBefore = false;
30
- /** @type {boolean} */
31
- this.allowAfter = false;
32
-
33
- switch (option) {
34
- case '!all':
35
- case 'all':
36
- this.allowBefore = true;
37
- this.allowAfter = true;
38
- break;
39
- default:
40
- this.allowBefore = false;
41
- this.allowAfter = false;
42
- break;
43
- }
44
- this.setParent(this.selector, this);
45
- }
46
-
47
- /** @param {TreeVisitor} visitor */
48
- accept(visitor) {
49
- this.selector = /** @type {Selector} */ (visitor.visit(this.selector));
50
- }
51
-
52
- /** @param {EvalContext} context */
53
- eval(context) {
54
- return new Extend(/** @type {Selector} */ (this.selector.eval(context)), this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo());
55
- }
56
-
57
- // remove when Nodes have JSDoc types
58
- // eslint-disable-next-line no-unused-vars
59
- /** @param {EvalContext} [context] */
60
- clone(context) {
61
- return new Extend(this.selector, this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo());
62
- }
63
-
64
- // it concatenates (joins) all selectors in selector array
65
- /** @param {Selector[]} selectors */
66
- findSelfSelectors(selectors) {
67
- /** @type {import('./element.js').default[]} */
68
- let selfElements = [];
69
- let i, selectorElements;
70
-
71
- for (i = 0; i < selectors.length; i++) {
72
- selectorElements = selectors[i].elements;
73
- // duplicate the logic in genCSS function inside the selector node.
74
- // future TODO - move both logics into the selector joiner visitor
75
- if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === '') {
76
- selectorElements[0].combinator.value = ' ';
77
- }
78
- selfElements = selfElements.concat(selectors[i].elements);
79
- }
80
-
81
- /** @type {Selector[]} */
82
- this.selfSelectors = [new Selector(selfElements)];
83
- this.selfSelectors[0].copyVisibilityInfo(this.visibilityInfo());
84
- }
85
- }
86
-
87
- Extend.next_id = 0;
88
- export default Extend;