less 4.8.1 → 5.0.0-alpha.1

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 (129) hide show
  1. package/README.md +19 -5
  2. package/bin/lessc +190 -630
  3. package/dist/less-node.cjs +398 -14282
  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 +33 -40
  13. package/dist/less.cjs +0 -14929
  14. package/dist/less.js +0 -14929
  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 -36
  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/parser-input.js +0 -400
  52. package/lib/less/parser/parser.js +0 -2894
  53. package/lib/less/plugin-manager.js +0 -168
  54. package/lib/less/render.js +0 -41
  55. package/lib/less/source-map-builder.js +0 -82
  56. package/lib/less/source-map-output.js +0 -151
  57. package/lib/less/transform-tree.js +0 -102
  58. package/lib/less/tree/anonymous.js +0 -57
  59. package/lib/less/tree/assignment.js +0 -48
  60. package/lib/less/tree/atrule-syntax.js +0 -8
  61. package/lib/less/tree/atrule.js +0 -340
  62. package/lib/less/tree/attribute.js +0 -63
  63. package/lib/less/tree/call.js +0 -132
  64. package/lib/less/tree/color.js +0 -285
  65. package/lib/less/tree/combinator.js +0 -38
  66. package/lib/less/tree/comment.js +0 -48
  67. package/lib/less/tree/condition.js +0 -65
  68. package/lib/less/tree/container.js +0 -104
  69. package/lib/less/tree/debug-info.js +0 -80
  70. package/lib/less/tree/declaration.js +0 -139
  71. package/lib/less/tree/detached-ruleset.js +0 -45
  72. package/lib/less/tree/dimension.js +0 -215
  73. package/lib/less/tree/element.js +0 -93
  74. package/lib/less/tree/expression.js +0 -100
  75. package/lib/less/tree/extend.js +0 -88
  76. package/lib/less/tree/import.js +0 -299
  77. package/lib/less/tree/index.js +0 -56
  78. package/lib/less/tree/javascript.js +0 -45
  79. package/lib/less/tree/js-eval-node.js +0 -74
  80. package/lib/less/tree/keyword.js +0 -28
  81. package/lib/less/tree/media.js +0 -90
  82. package/lib/less/tree/merge-rules.js +0 -47
  83. package/lib/less/tree/mixin-call.js +0 -283
  84. package/lib/less/tree/mixin-definition.js +0 -319
  85. package/lib/less/tree/namespace-value.js +0 -95
  86. package/lib/less/tree/negative.js +0 -37
  87. package/lib/less/tree/nested-at-rule.js +0 -198
  88. package/lib/less/tree/node.js +0 -310
  89. package/lib/less/tree/operation.js +0 -81
  90. package/lib/less/tree/paren.js +0 -41
  91. package/lib/less/tree/property.js +0 -96
  92. package/lib/less/tree/query-in-parens.js +0 -64
  93. package/lib/less/tree/quoted.js +0 -114
  94. package/lib/less/tree/ruleset.js +0 -1066
  95. package/lib/less/tree/selector.js +0 -201
  96. package/lib/less/tree/unicode-descriptor.js +0 -14
  97. package/lib/less/tree/unit.js +0 -170
  98. package/lib/less/tree/url.js +0 -83
  99. package/lib/less/tree/value.js +0 -60
  100. package/lib/less/tree/variable-call.js +0 -60
  101. package/lib/less/tree/variable.js +0 -85
  102. package/lib/less/utils.js +0 -126
  103. package/lib/less/visitors/extend-visitor.js +0 -505
  104. package/lib/less/visitors/import-sequencer.js +0 -56
  105. package/lib/less/visitors/import-visitor.js +0 -203
  106. package/lib/less/visitors/index.js +0 -15
  107. package/lib/less/visitors/join-selector-visitor.js +0 -65
  108. package/lib/less/visitors/set-tree-visibility-visitor.js +0 -57
  109. package/lib/less/visitors/to-css-visitor.js +0 -332
  110. package/lib/less/visitors/visitor.js +0 -165
  111. package/lib/less-browser/add-default-options.js +0 -53
  112. package/lib/less-browser/bootstrap.js +0 -67
  113. package/lib/less-browser/browser.js +0 -65
  114. package/lib/less-browser/cache.js +0 -43
  115. package/lib/less-browser/error-reporting.js +0 -170
  116. package/lib/less-browser/file-manager.js +0 -112
  117. package/lib/less-browser/image-size.js +0 -28
  118. package/lib/less-browser/index.js +0 -284
  119. package/lib/less-browser/log-listener.js +0 -42
  120. package/lib/less-browser/plugin-loader.js +0 -24
  121. package/lib/less-browser/utils.js +0 -30
  122. package/lib/less-node/environment.js +0 -43
  123. package/lib/less-node/file-manager.js +0 -156
  124. package/lib/less-node/fs.js +0 -14
  125. package/lib/less-node/image-size.js +0 -78
  126. package/lib/less-node/index.js +0 -31
  127. package/lib/less-node/lessc-helper.js +0 -95
  128. package/lib/less-node/plugin-loader.js +0 -62
  129. 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;