less 4.9.0 → 5.0.0-alpha.2

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 (131) hide show
  1. package/README.md +19 -5
  2. package/bin/lessc +190 -630
  3. package/dist/less-node.cjs +399 -14570
  4. package/index.cjs +5 -2
  5. package/lib/index.js +164 -0
  6. package/lib/lessc-helper.js +52 -0
  7. package/lib/logger.js +76 -0
  8. package/lib/options.d.ts +46 -0
  9. package/lib/options.js +145 -0
  10. package/lib/types.js +20 -0
  11. package/lib/version.js +19 -0
  12. package/package.json +32 -39
  13. package/dist/less.cjs +0 -15215
  14. package/dist/less.js +0 -15215
  15. package/dist/less.min.js +0 -11
  16. package/dist/less.min.js.map +0 -1
  17. package/lib/less/constants.js +0 -13
  18. package/lib/less/contexts.js +0 -165
  19. package/lib/less/data/colors.js +0 -150
  20. package/lib/less/data/index.js +0 -4
  21. package/lib/less/data/unit-conversions.js +0 -21
  22. package/lib/less/default-options.js +0 -89
  23. package/lib/less/deprecation.js +0 -82
  24. package/lib/less/environment/abstract-file-manager.js +0 -140
  25. package/lib/less/environment/abstract-plugin-loader.js +0 -185
  26. package/lib/less/environment/environment-api.ts +0 -21
  27. package/lib/less/environment/environment.js +0 -59
  28. package/lib/less/environment/file-manager-api.ts +0 -77
  29. package/lib/less/functions/boolean.js +0 -29
  30. package/lib/less/functions/color-blending.js +0 -85
  31. package/lib/less/functions/color.js +0 -452
  32. package/lib/less/functions/data-uri.js +0 -74
  33. package/lib/less/functions/default.js +0 -26
  34. package/lib/less/functions/function-caller.js +0 -55
  35. package/lib/less/functions/function-registry.js +0 -36
  36. package/lib/less/functions/index.js +0 -35
  37. package/lib/less/functions/list.js +0 -158
  38. package/lib/less/functions/math-helper.js +0 -22
  39. package/lib/less/functions/math.js +0 -30
  40. package/lib/less/functions/number.js +0 -95
  41. package/lib/less/functions/string.js +0 -39
  42. package/lib/less/functions/style.js +0 -29
  43. package/lib/less/functions/svg.js +0 -87
  44. package/lib/less/functions/types.js +0 -70
  45. package/lib/less/import-manager.js +0 -183
  46. package/lib/less/index.js +0 -95
  47. package/lib/less/less-error.js +0 -166
  48. package/lib/less/logger.js +0 -34
  49. package/lib/less/parse-tree.js +0 -124
  50. package/lib/less/parse.js +0 -87
  51. package/lib/less/parser/lookup-pattern.js +0 -26
  52. package/lib/less/parser/parser-input.js +0 -400
  53. package/lib/less/parser/parser.js +0 -2998
  54. package/lib/less/plugin-manager.js +0 -168
  55. package/lib/less/render.js +0 -41
  56. package/lib/less/source-map-builder.js +0 -82
  57. package/lib/less/source-map-output.js +0 -151
  58. package/lib/less/transform-tree.js +0 -102
  59. package/lib/less/tree/anonymous.js +0 -61
  60. package/lib/less/tree/assignment.js +0 -48
  61. package/lib/less/tree/atrule-syntax.js +0 -8
  62. package/lib/less/tree/atrule.js +0 -340
  63. package/lib/less/tree/attribute.js +0 -63
  64. package/lib/less/tree/call.js +0 -132
  65. package/lib/less/tree/color.js +0 -285
  66. package/lib/less/tree/combinator.js +0 -38
  67. package/lib/less/tree/comment.js +0 -48
  68. package/lib/less/tree/condition.js +0 -65
  69. package/lib/less/tree/container.js +0 -104
  70. package/lib/less/tree/debug-info.js +0 -80
  71. package/lib/less/tree/declaration.js +0 -139
  72. package/lib/less/tree/detached-ruleset.js +0 -45
  73. package/lib/less/tree/dimension.js +0 -215
  74. package/lib/less/tree/element.js +0 -93
  75. package/lib/less/tree/expression.js +0 -100
  76. package/lib/less/tree/extend.js +0 -88
  77. package/lib/less/tree/import.js +0 -299
  78. package/lib/less/tree/index.js +0 -56
  79. package/lib/less/tree/interpolated-variable.js +0 -106
  80. package/lib/less/tree/javascript.js +0 -45
  81. package/lib/less/tree/js-eval-node.js +0 -80
  82. package/lib/less/tree/keyword.js +0 -28
  83. package/lib/less/tree/media.js +0 -90
  84. package/lib/less/tree/merge-rules.js +0 -47
  85. package/lib/less/tree/mixin-call.js +0 -283
  86. package/lib/less/tree/mixin-definition.js +0 -319
  87. package/lib/less/tree/namespace-value.js +0 -95
  88. package/lib/less/tree/negative.js +0 -37
  89. package/lib/less/tree/nested-at-rule.js +0 -239
  90. package/lib/less/tree/node.js +0 -310
  91. package/lib/less/tree/operation.js +0 -81
  92. package/lib/less/tree/paren.js +0 -41
  93. package/lib/less/tree/property.js +0 -96
  94. package/lib/less/tree/query-in-parens.js +0 -64
  95. package/lib/less/tree/quoted.js +0 -131
  96. package/lib/less/tree/ruleset.js +0 -1068
  97. package/lib/less/tree/selector.js +0 -201
  98. package/lib/less/tree/unicode-descriptor.js +0 -14
  99. package/lib/less/tree/unit.js +0 -170
  100. package/lib/less/tree/url.js +0 -83
  101. package/lib/less/tree/value.js +0 -60
  102. package/lib/less/tree/variable-call.js +0 -60
  103. package/lib/less/tree/variable.js +0 -85
  104. package/lib/less/utils.js +0 -126
  105. package/lib/less/visitors/extend-visitor.js +0 -505
  106. package/lib/less/visitors/import-sequencer.js +0 -56
  107. package/lib/less/visitors/import-visitor.js +0 -203
  108. package/lib/less/visitors/index.js +0 -15
  109. package/lib/less/visitors/join-selector-visitor.js +0 -65
  110. package/lib/less/visitors/set-tree-visibility-visitor.js +0 -57
  111. package/lib/less/visitors/to-css-visitor.js +0 -332
  112. package/lib/less/visitors/visitor.js +0 -165
  113. package/lib/less-browser/add-default-options.js +0 -53
  114. package/lib/less-browser/bootstrap.js +0 -67
  115. package/lib/less-browser/browser.js +0 -65
  116. package/lib/less-browser/cache.js +0 -43
  117. package/lib/less-browser/error-reporting.js +0 -170
  118. package/lib/less-browser/file-manager.js +0 -112
  119. package/lib/less-browser/image-size.js +0 -28
  120. package/lib/less-browser/index.js +0 -284
  121. package/lib/less-browser/log-listener.js +0 -42
  122. package/lib/less-browser/plugin-loader.js +0 -24
  123. package/lib/less-browser/utils.js +0 -30
  124. package/lib/less-node/environment.js +0 -43
  125. package/lib/less-node/file-manager.js +0 -156
  126. package/lib/less-node/fs.js +0 -14
  127. package/lib/less-node/image-size.js +0 -78
  128. package/lib/less-node/index.js +0 -31
  129. package/lib/less-node/lessc-helper.js +0 -95
  130. package/lib/less-node/plugin-loader.js +0 -62
  131. package/lib/less-node/url-file-manager.js +0 -60
@@ -1,340 +0,0 @@
1
- // @ts-check
2
- /** @import { EvalContext, CSSOutput, TreeVisitor, FileInfo, VisibilityInfo } from './node.js' */
3
- /** @import { FunctionRegistry } from './nested-at-rule.js' */
4
- import Node from './node.js';
5
- import Selector from './selector.js';
6
- import Ruleset from './ruleset.js';
7
- import Anonymous from './anonymous.js';
8
- import NestableAtRulePrototype from './nested-at-rule.js';
9
- import mergeRules from './merge-rules.js';
10
-
11
- /**
12
- * @typedef {Node & {
13
- * rules?: Node[],
14
- * selectors?: Selector[],
15
- * root?: boolean,
16
- * allowImports?: boolean,
17
- * functionRegistry?: FunctionRegistry,
18
- * merge?: boolean,
19
- * debugInfo?: { lineNumber: number, fileName: string },
20
- * elements?: import('./element.js').default[]
21
- * }} RulesetLikeNode
22
- */
23
-
24
- class AtRule extends Node {
25
- get type() { return 'AtRule'; }
26
-
27
- /**
28
- * @param {string} [name]
29
- * @param {Node | string} [value]
30
- * @param {Node[] | Ruleset} [rules]
31
- * @param {number} [index]
32
- * @param {FileInfo} [currentFileInfo]
33
- * @param {{ lineNumber: number, fileName: string }} [debugInfo]
34
- * @param {boolean} [isRooted]
35
- * @param {VisibilityInfo} [visibilityInfo]
36
- */
37
- constructor(
38
- name,
39
- value,
40
- rules,
41
- index,
42
- currentFileInfo,
43
- debugInfo,
44
- isRooted,
45
- visibilityInfo
46
- ) {
47
- super();
48
- let i;
49
- var selectors = (new Selector([], null, null, index, currentFileInfo)).createEmptySelectors();
50
-
51
- /** @type {string | undefined} */
52
- this.name = name;
53
- this.value = (value instanceof Node) ? value : (value ? new Anonymous(value) : value);
54
- /** @type {boolean | undefined} */
55
- this.simpleBlock = undefined;
56
- /** @type {RulesetLikeNode[] | undefined} */
57
- this.declarations = undefined;
58
- /** @type {RulesetLikeNode[] | undefined} */
59
- this.rules = undefined;
60
- if (rules) {
61
- if (Array.isArray(rules)) {
62
- const allDeclarations = this.declarationsBlock(rules);
63
-
64
- let allRulesetDeclarations = true;
65
- rules.forEach(rule => {
66
- if (rule.type === 'Ruleset' && /** @type {RulesetLikeNode} */ (rule).rules) allRulesetDeclarations = allRulesetDeclarations && this.declarationsBlock(/** @type {Node[]} */ (/** @type {RulesetLikeNode} */ (rule).rules), true);
67
- });
68
-
69
- if (allDeclarations && !isRooted) {
70
- this.simpleBlock = true;
71
- this.declarations = rules;
72
- } else if (allRulesetDeclarations && rules.length === 1 && !isRooted && !value) {
73
- this.simpleBlock = true;
74
- this.declarations = /** @type {RulesetLikeNode} */ (rules[0]).rules ? /** @type {RulesetLikeNode} */ (rules[0]).rules : rules;
75
- } else {
76
- this.rules = rules;
77
- }
78
- } else {
79
- const allDeclarations = this.declarationsBlock(/** @type {Node[]} */ (rules.rules));
80
-
81
- if (allDeclarations && !isRooted && !value) {
82
- this.simpleBlock = true;
83
- this.declarations = rules.rules;
84
- } else {
85
- this.rules = [rules];
86
- /** @type {RulesetLikeNode} */ (this.rules[0]).selectors = (new Selector([], null, null, index, currentFileInfo)).createEmptySelectors();
87
- }
88
- }
89
- if (!this.simpleBlock) {
90
- for (i = 0; i < this.rules.length; i++) {
91
- /** @type {RulesetLikeNode} */ (this.rules[i]).allowImports = true;
92
- }
93
- }
94
- if (this.declarations) {
95
- this.setParent(this.declarations, /** @type {Node} */ (/** @type {unknown} */ (this)));
96
- }
97
- if (this.rules) {
98
- this.setParent(this.rules, /** @type {Node} */ (/** @type {unknown} */ (this)));
99
- }
100
- }
101
- this._index = index;
102
- this._fileInfo = currentFileInfo;
103
- /** @type {{ lineNumber: number, fileName: string } | undefined} */
104
- this.debugInfo = debugInfo;
105
- /** @type {boolean} */
106
- this.isRooted = isRooted || false;
107
- this.copyVisibilityInfo(visibilityInfo);
108
- this.allowRoot = true;
109
- }
110
-
111
- /**
112
- * @param {Node[]} rules
113
- * @param {boolean} [mergeable]
114
- * @returns {boolean}
115
- */
116
- declarationsBlock(rules, mergeable = false) {
117
- if (!mergeable) {
118
- return rules.filter(function (/** @type {Node & { merge?: boolean }} */ node) { return (node.type === 'Declaration' || node.type === 'Comment') && !node.merge}).length === rules.length;
119
- } else {
120
- return rules.filter(function (/** @type {Node} */ node) { return (node.type === 'Declaration' || node.type === 'Comment'); }).length === rules.length;
121
- }
122
- }
123
-
124
- /**
125
- * @param {Node[]} rules
126
- * @returns {boolean}
127
- */
128
- keywordList(rules) {
129
- if (!Array.isArray(rules)) {
130
- return false;
131
- } else {
132
- return rules.filter(function (/** @type {Node} */ node) { return (node.type === 'Keyword' || node.type === 'Comment'); }).length === rules.length;
133
- }
134
- }
135
-
136
- /** @param {TreeVisitor} visitor */
137
- accept(visitor) {
138
- const value = this.value, rules = this.rules, declarations = this.declarations;
139
-
140
- if (rules) {
141
- this.rules = visitor.visitArray(rules);
142
- } else if (declarations) {
143
- this.declarations = visitor.visitArray(declarations);
144
- }
145
- if (value) {
146
- this.value = visitor.visit(/** @type {Node} */ (value));
147
- }
148
- }
149
-
150
- /** @override @returns {boolean} */
151
- isRulesetLike() {
152
- return /** @type {boolean} */ (/** @type {unknown} */ (this.rules || !this.isCharset()));
153
- }
154
-
155
- isCharset() {
156
- return '@charset' === this.name;
157
- }
158
-
159
- /**
160
- * @param {EvalContext} context
161
- * @param {CSSOutput} output
162
- */
163
- genCSS(context, output) {
164
- const value = this.value, rules = this.rules || this.declarations;
165
- output.add(/** @type {string} */ (this.name), this.fileInfo(), this.getIndex());
166
- if (value) {
167
- output.add(' ');
168
- /** @type {Node} */ (value).genCSS(context, output);
169
- }
170
- if (this.simpleBlock) {
171
- this.outputRuleset(context, output, /** @type {Node[]} */ (this.declarations));
172
- } else if (rules) {
173
- this.outputRuleset(context, output, rules);
174
- } else {
175
- output.add(';');
176
- }
177
- }
178
-
179
- /**
180
- * @param {EvalContext} context
181
- * @returns {Node}
182
- */
183
- eval(context) {
184
- let mediaPathBackup, mediaBlocksBackup, value = this.value, rules = this.rules || this.declarations;
185
-
186
- // media stored inside other atrule should not bubble over it
187
- // backpup media bubbling information
188
- mediaPathBackup = context.mediaPath;
189
- mediaBlocksBackup = context.mediaBlocks;
190
- // deleted media bubbling information
191
- context.mediaPath = [];
192
- context.mediaBlocks = [];
193
-
194
- if (value) {
195
- value = /** @type {Node} */ (value).eval(context);
196
- }
197
-
198
- if (rules) {
199
- rules = this.evalRoot(context, rules);
200
- }
201
- if (Array.isArray(rules) && /** @type {RulesetLikeNode} */ (rules[0]).rules && Array.isArray(/** @type {RulesetLikeNode} */ (rules[0]).rules) && /** @type {Node[]} */ (/** @type {RulesetLikeNode} */ (rules[0]).rules).length) {
202
- const allMergeableDeclarations = this.declarationsBlock(/** @type {Node[]} */ (/** @type {RulesetLikeNode} */ (rules[0]).rules), true);
203
- if (allMergeableDeclarations && !this.isRooted && !value) {
204
- mergeRules(/** @type {Node[]} */ (/** @type {RulesetLikeNode} */ (rules[0]).rules));
205
- rules = /** @type {RulesetLikeNode[]} */ (/** @type {RulesetLikeNode} */ (rules[0]).rules);
206
- rules.forEach(/** @param {RulesetLikeNode} rule */ rule => { rule.merge = false; });
207
- }
208
- }
209
- if (this.simpleBlock && rules) {
210
- /** @type {RulesetLikeNode} */ (rules[0]).functionRegistry = /** @type {RulesetLikeNode} */ (context.frames[0]).functionRegistry.inherit();
211
- rules = rules.map(function (/** @type {Node} */ rule) { return rule.eval(context); });
212
- }
213
-
214
- // restore media bubbling information
215
- context.mediaPath = mediaPathBackup;
216
- context.mediaBlocks = mediaBlocksBackup;
217
- return /** @type {Node} */ (/** @type {unknown} */ (new AtRule(this.name, value, rules, this.getIndex(), this.fileInfo(), this.debugInfo, this.isRooted, this.visibilityInfo())));
218
- }
219
-
220
- /**
221
- * @param {EvalContext} context
222
- * @param {Node[]} rules
223
- * @returns {Node[]}
224
- */
225
- evalRoot(context, rules) {
226
- let ampersandCount = 0;
227
- let noAmpersandCount = 0;
228
- let noAmpersands = true;
229
-
230
- if (!this.simpleBlock) {
231
- rules = [rules[0].eval(context)];
232
- }
233
-
234
- /** @type {Selector[]} */
235
- let precedingSelectors = [];
236
- if (context.frames.length > 0) {
237
- for (let index = 0; index < context.frames.length; index++) {
238
- const frame = /** @type {RulesetLikeNode} */ (context.frames[index]);
239
- if (
240
- frame.type === 'Ruleset' &&
241
- frame.rules &&
242
- frame.rules.length > 0
243
- ) {
244
- if (frame && !frame.root && frame.selectors && frame.selectors.length > 0) {
245
- precedingSelectors = precedingSelectors.concat(frame.selectors);
246
- }
247
- }
248
- if (precedingSelectors.length > 0) {
249
- const allAmpersandElements = precedingSelectors.every(
250
- sel => sel.elements && sel.elements.length > 0 && sel.elements.every(
251
- /** @param {import('./element.js').default} el */
252
- el => el.value === '&'
253
- )
254
- );
255
- if (allAmpersandElements) {
256
- noAmpersands = false;
257
- noAmpersandCount++;
258
- } else {
259
- ampersandCount++;
260
- }
261
- }
262
- }
263
- }
264
-
265
- const mixedAmpersands = ampersandCount > 0 && noAmpersandCount > 0 && !noAmpersands;
266
- if (
267
- (this.isRooted && ampersandCount > 0 && noAmpersandCount === 0 && noAmpersands)
268
- || !mixedAmpersands
269
- ) {
270
- /** @type {RulesetLikeNode} */ (rules[0]).root = true;
271
- }
272
- return rules;
273
- }
274
-
275
- /** @param {string} name */
276
- variable(name) {
277
- if (this.rules) {
278
- // assuming that there is only one rule at this point - that is how parser constructs the rule
279
- return Ruleset.prototype.variable.call(this.rules[0], name);
280
- }
281
- }
282
-
283
- find() {
284
- if (this.rules) {
285
- // assuming that there is only one rule at this point - that is how parser constructs the rule
286
- return Ruleset.prototype.find.apply(this.rules[0], arguments);
287
- }
288
- }
289
-
290
- rulesets() {
291
- if (this.rules) {
292
- // assuming that there is only one rule at this point - that is how parser constructs the rule
293
- return Ruleset.prototype.rulesets.apply(this.rules[0]);
294
- }
295
- }
296
-
297
- /**
298
- * @param {EvalContext} context
299
- * @param {CSSOutput} output
300
- * @param {Node[]} rules
301
- */
302
- outputRuleset(context, output, rules) {
303
- const ruleCnt = rules.length;
304
- let i;
305
- context.tabLevel = (context.tabLevel | 0) + 1;
306
-
307
- // Compressed
308
- if (context.compress) {
309
- output.add('{');
310
- for (i = 0; i < ruleCnt; i++) {
311
- rules[i].genCSS(context, output);
312
- }
313
- output.add('}');
314
- context.tabLevel--;
315
- return;
316
- }
317
-
318
- // Non-compressed
319
- const tabSetStr = `\n${Array(context.tabLevel).join(' ')}`, tabRuleStr = `${tabSetStr} `;
320
- if (!ruleCnt) {
321
- output.add(` {${tabSetStr}}`);
322
- } else {
323
- output.add(` {${tabRuleStr}`);
324
- rules[0].genCSS(context, output);
325
- for (i = 1; i < ruleCnt; i++) {
326
- output.add(tabRuleStr);
327
- rules[i].genCSS(context, output);
328
- }
329
- output.add(`${tabSetStr}}`);
330
- }
331
-
332
- context.tabLevel--;
333
- }
334
- }
335
-
336
- // Apply shared methods from NestableAtRulePrototype that AtRule doesn't override
337
- const { evalFunction, evalTop, evalNested, permute, bubbleSelectors } = NestableAtRulePrototype;
338
- Object.assign(AtRule.prototype, { evalFunction, evalTop, evalNested, permute, bubbleSelectors });
339
-
340
- export default AtRule;
@@ -1,63 +0,0 @@
1
- // @ts-check
2
- /** @import { EvalContext, CSSOutput } from './node.js' */
3
- import Node from './node.js';
4
-
5
- class Attribute extends Node {
6
- get type() { return 'Attribute'; }
7
-
8
- /**
9
- * @param {string | Node} key
10
- * @param {string} op
11
- * @param {string | Node} value
12
- * @param {string} cif
13
- */
14
- constructor(key, op, value, cif) {
15
- super();
16
- this.key = key;
17
- this.op = op;
18
- this.value = value;
19
- this.cif = cif;
20
- }
21
-
22
- /**
23
- * @param {EvalContext} context
24
- * @returns {Attribute}
25
- */
26
- eval(context) {
27
- return new Attribute(
28
- /** @type {Node} */ (this.key).eval ? /** @type {Node} */ (this.key).eval(context) : /** @type {string} */ (this.key),
29
- this.op,
30
- (this.value && /** @type {Node} */ (this.value).eval) ? /** @type {Node} */ (this.value).eval(context) : this.value,
31
- this.cif
32
- );
33
- }
34
-
35
- /**
36
- * @param {EvalContext} context
37
- * @param {CSSOutput} output
38
- */
39
- genCSS(context, output) {
40
- output.add(this.toCSS(context));
41
- }
42
-
43
- /**
44
- * @param {EvalContext} context
45
- * @returns {string}
46
- */
47
- toCSS(context) {
48
- let value = /** @type {Node} */ (this.key).toCSS ? /** @type {Node} */ (this.key).toCSS(context) : /** @type {string} */ (this.key);
49
-
50
- if (this.op) {
51
- value += this.op;
52
- value += (/** @type {Node} */ (this.value).toCSS ? /** @type {Node} */ (this.value).toCSS(context) : /** @type {string} */ (this.value));
53
- }
54
-
55
- if (this.cif) {
56
- value = value + ' ' + this.cif;
57
- }
58
-
59
- return `[${value}]`;
60
- }
61
- }
62
-
63
- export default Attribute;
@@ -1,132 +0,0 @@
1
- // @ts-check
2
- /** @import { EvalContext, CSSOutput, TreeVisitor, FileInfo } from './node.js' */
3
- import Node from './node.js';
4
- import Anonymous from './anonymous.js';
5
- import FunctionCaller from '../functions/function-caller.js';
6
-
7
- //
8
- // A function call node.
9
- //
10
- class Call extends Node {
11
- get type() { return 'Call'; }
12
-
13
- /**
14
- * @param {string} name
15
- * @param {Node[]} args
16
- * @param {number} index
17
- * @param {FileInfo} currentFileInfo
18
- */
19
- constructor(name, args, index, currentFileInfo) {
20
- super();
21
- this.name = name;
22
- this.args = args;
23
- this.calc = name === 'calc';
24
- this._index = index;
25
- this._fileInfo = currentFileInfo;
26
- }
27
-
28
- /** @param {TreeVisitor} visitor */
29
- accept(visitor) {
30
- if (this.args) {
31
- this.args = visitor.visitArray(this.args);
32
- }
33
- }
34
-
35
- //
36
- // When evaluating a function call,
37
- // we either find the function in the functionRegistry,
38
- // in which case we call it, passing the evaluated arguments,
39
- // if this returns null or we cannot find the function, we
40
- // simply print it out as it appeared originally [2].
41
- //
42
- // The reason why we evaluate the arguments, is in the case where
43
- // we try to pass a variable to a function, like: `saturate(@color)`.
44
- // The function should receive the value, not the variable.
45
- //
46
- /**
47
- * @param {EvalContext} context
48
- * @returns {Node}
49
- */
50
- eval(context) {
51
- /**
52
- * Turn off math for calc(), and switch back on for evaluating nested functions
53
- */
54
- const currentMathContext = context.mathOn;
55
- context.mathOn = !this.calc;
56
- if (this.calc || context.inCalc) {
57
- context.enterCalc();
58
- }
59
-
60
- const exitCalc = () => {
61
- if (this.calc || context.inCalc) {
62
- context.exitCalc();
63
- }
64
- context.mathOn = currentMathContext;
65
- };
66
-
67
- /** @type {Node | string | boolean | null | undefined} */
68
- let result;
69
- const funcCaller = new FunctionCaller(this.name, context, this.getIndex(), this.fileInfo());
70
-
71
- if (funcCaller.isValid()) {
72
- try {
73
- result = funcCaller.call(this.args);
74
- exitCalc();
75
- } catch (e) {
76
- // eslint-disable-next-line no-prototype-builtins
77
- if (/** @type {Record<string, unknown>} */ (e).hasOwnProperty('line') && /** @type {Record<string, unknown>} */ (e).hasOwnProperty('column')) {
78
- throw e;
79
- }
80
- throw {
81
- type: /** @type {Record<string, string>} */ (e).type || 'Runtime',
82
- message: `Error evaluating function \`${this.name}\`${/** @type {Error} */ (e).message ? `: ${/** @type {Error} */ (e).message}` : ''}`,
83
- index: this.getIndex(),
84
- filename: this.fileInfo().filename,
85
- line: /** @type {Record<string, number>} */ (e).lineNumber,
86
- column: /** @type {Record<string, number>} */ (e).columnNumber
87
- };
88
- }
89
- }
90
-
91
- if (result !== null && result !== undefined) {
92
- // Results that that are not nodes are cast as Anonymous nodes
93
- // Falsy values or booleans are returned as empty nodes
94
- if (!(result instanceof Node)) {
95
- if (!result || result === true) {
96
- result = new Anonymous(null);
97
- }
98
- else {
99
- result = new Anonymous(result.toString());
100
- }
101
-
102
- }
103
- result._index = this._index;
104
- result._fileInfo = this._fileInfo;
105
- return result;
106
- }
107
-
108
- const args = this.args.map(a => a.eval(context));
109
- exitCalc();
110
-
111
- return new Call(this.name, args, this.getIndex(), this.fileInfo());
112
- }
113
-
114
- /**
115
- * @param {EvalContext} context
116
- * @param {CSSOutput} output
117
- */
118
- genCSS(context, output) {
119
- output.add(`${this.name}(`, this.fileInfo(), this.getIndex());
120
-
121
- for (let i = 0; i < this.args.length; i++) {
122
- this.args[i].genCSS(context, output);
123
- if (i + 1 < this.args.length) {
124
- output.add(', ');
125
- }
126
- }
127
-
128
- output.add(')');
129
- }
130
- }
131
-
132
- export default Call;