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,283 +0,0 @@
1
- // @ts-check
2
- /** @import { EvalContext, TreeVisitor, FileInfo } 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 MixinDefinition from './mixin-definition.js';
7
- import defaultFunc from '../functions/default.js';
8
-
9
- /**
10
- * @typedef {{ name?: string, value: Node, expand?: boolean }} MixinArg
11
- */
12
-
13
- /**
14
- * @typedef {Node & {
15
- * rules?: Node[],
16
- * selectors?: Selector[],
17
- * originalRuleset?: Node,
18
- * matchArgs: (args: MixinArg[] | null, context: EvalContext) => boolean,
19
- * matchCondition?: (args: MixinArg[] | null, context: EvalContext) => boolean,
20
- * find: (selector: Selector, self?: Node | null, filter?: (rule: Node) => boolean) => Array<{ rule: Node & { rules?: Node[], originalRuleset?: Node, matchArgs: Function, matchCondition?: Function, evalCall?: Function }, path: Node[] }>,
21
- * functionRegistry?: FunctionRegistry
22
- * }} MixinSearchFrame
23
- */
24
-
25
- class MixinCall extends Node {
26
- get type() { return 'MixinCall'; }
27
-
28
- /**
29
- * @param {import('./element.js').default[]} elements
30
- * @param {MixinArg[]} [args]
31
- * @param {number} [index]
32
- * @param {FileInfo} [currentFileInfo]
33
- * @param {string} [important]
34
- */
35
- constructor(elements, args, index, currentFileInfo, important) {
36
- super();
37
- /** @type {Selector} */
38
- this.selector = new Selector(elements);
39
- /** @type {MixinArg[]} */
40
- this.arguments = args || [];
41
- this._index = index;
42
- this._fileInfo = currentFileInfo;
43
- /** @type {string | undefined} */
44
- this.important = important;
45
- this.allowRoot = true;
46
- this.setParent(this.selector, /** @type {Node} */ (/** @type {unknown} */ (this)));
47
- }
48
-
49
- /** @param {TreeVisitor} visitor */
50
- accept(visitor) {
51
- if (this.selector) {
52
- this.selector = /** @type {Selector} */ (visitor.visit(this.selector));
53
- }
54
- if (this.arguments.length) {
55
- this.arguments = /** @type {MixinArg[]} */ (/** @type {unknown} */ (visitor.visitArray(/** @type {Node[]} */ (/** @type {unknown} */ (this.arguments)))));
56
- }
57
- }
58
-
59
- /**
60
- * @param {EvalContext} context
61
- * @returns {Node}
62
- */
63
- eval(context) {
64
- /** @type {{ rule: Node & { rules?: Node[], originalRuleset?: Node, matchArgs: Function, matchCondition?: Function, evalCall?: Function }, path: Node[] }[] | undefined} */
65
- let mixins;
66
- /** @type {Node & { rules?: Node[], originalRuleset?: Node, matchArgs: Function, matchCondition?: Function, evalCall?: Function }} */
67
- let mixin;
68
- /** @type {Node[]} */
69
- let mixinPath;
70
- /** @type {MixinArg[]} */
71
- const args = [];
72
- /** @type {MixinArg} */
73
- let arg;
74
- /** @type {Node} */
75
- let argValue;
76
- /** @type {Node[]} */
77
- const rules = [];
78
- let match = false;
79
- /** @type {number} */
80
- let i;
81
- /** @type {number} */
82
- let m;
83
- /** @type {number} */
84
- let f;
85
- /** @type {boolean} */
86
- let isRecursive;
87
- /** @type {boolean | undefined} */
88
- let isOneFound;
89
- /** @type {{ mixin: Node & { rules?: Node[], originalRuleset?: Node, matchArgs: Function, matchCondition?: Function, evalCall?: Function }, group: number }[]} */
90
- const candidates = [];
91
- /** @type {{ mixin: Node & { rules?: Node[], originalRuleset?: Node, matchArgs: Function, matchCondition?: Function, evalCall?: Function }, group: number } | number} */
92
- let candidate;
93
- /** @type {boolean[]} */
94
- const conditionResult = [];
95
- /** @type {number | undefined} */
96
- let defaultResult;
97
- const defFalseEitherCase = -1;
98
- const defNone = 0;
99
- const defTrue = 1;
100
- const defFalse = 2;
101
- /** @type {number[]} */
102
- let count;
103
- /** @type {Node | undefined} */
104
- let originalRuleset;
105
- /** @type {((rule: MixinSearchFrame) => boolean) | undefined} */
106
- let noArgumentsFilter;
107
-
108
- this.selector = /** @type {Selector} */ (this.selector.eval(context));
109
-
110
- /**
111
- * @param {Node & { matchCondition?: Function }} mixin
112
- * @param {Node[]} mixinPath
113
- */
114
- function calcDefGroup(mixin, mixinPath) {
115
- /** @type {number} */
116
- let f;
117
- /** @type {number} */
118
- let p;
119
- /** @type {Node & { matchCondition?: Function }} */
120
- let namespace;
121
-
122
- for (f = 0; f < 2; f++) {
123
- conditionResult[f] = true;
124
- defaultFunc.value(f);
125
- for (p = 0; p < mixinPath.length && conditionResult[f]; p++) {
126
- namespace = mixinPath[p];
127
- if (namespace.matchCondition) {
128
- conditionResult[f] = conditionResult[f] && namespace.matchCondition(null, context);
129
- }
130
- }
131
- if (mixin.matchCondition) {
132
- conditionResult[f] = conditionResult[f] && mixin.matchCondition(args, context);
133
- }
134
- }
135
- if (conditionResult[0] || conditionResult[1]) {
136
- if (conditionResult[0] != conditionResult[1]) {
137
- return conditionResult[1] ?
138
- defTrue : defFalse;
139
- }
140
-
141
- return defNone;
142
- }
143
- return defFalseEitherCase;
144
- }
145
-
146
- for (i = 0; i < this.arguments.length; i++) {
147
- arg = this.arguments[i];
148
- argValue = arg.value.eval(context);
149
- if (arg.expand && Array.isArray(argValue.value)) {
150
- const expandedValues = /** @type {Node[]} */ (argValue.value);
151
- for (m = 0; m < expandedValues.length; m++) {
152
- args.push({value: expandedValues[m]});
153
- }
154
- } else if (argValue.type === 'Expression' && Array.isArray(argValue.value) && argValue.value.length === 0) {
155
- // an unset variadic holds no captured args; omit it so the callee
156
- // falls through to its own parameter defaults instead of receiving empty
157
-
158
- } else {
159
- args.push({name: arg.name, value: argValue});
160
- }
161
- }
162
-
163
- noArgumentsFilter = function(/** @type {MixinSearchFrame} */ rule) {return rule.matchArgs(null, context);};
164
-
165
- for (i = 0; i < context.frames.length; i++) {
166
- if ((mixins = /** @type {MixinSearchFrame} */ (context.frames[i]).find(this.selector, null, /** @type {(rule: Node) => boolean} */ (/** @type {unknown} */ (noArgumentsFilter)))).length > 0) {
167
- isOneFound = true;
168
-
169
- // To make `default()` function independent of definition order we have two "subpasses" here.
170
- // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`),
171
- // and build candidate list with corresponding flags. Then, when we know all possible matches,
172
- // we make a final decision.
173
-
174
- for (m = 0; m < mixins.length; m++) {
175
- mixin = mixins[m].rule;
176
- mixinPath = mixins[m].path;
177
- isRecursive = false;
178
- for (f = 0; f < context.frames.length; f++) {
179
- if ((!(mixin instanceof MixinDefinition)) && mixin === (/** @type {Node & { originalRuleset?: Node }} */ (context.frames[f]).originalRuleset || context.frames[f])) {
180
- isRecursive = true;
181
- break;
182
- }
183
- }
184
- if (isRecursive) {
185
- continue;
186
- }
187
-
188
- if (mixin.matchArgs(args, context)) {
189
- candidate = {mixin, group: calcDefGroup(mixin, mixinPath)};
190
-
191
- if (/** @type {{ mixin: Node, group: number }} */ (candidate).group !== defFalseEitherCase) {
192
- candidates.push(/** @type {{ mixin: Node & { rules?: Node[], originalRuleset?: Node, matchArgs: Function, matchCondition?: Function, evalCall?: Function }, group: number }} */ (candidate));
193
- }
194
-
195
- match = true;
196
- }
197
- }
198
-
199
- defaultFunc.reset();
200
-
201
- count = [0, 0, 0];
202
- for (m = 0; m < candidates.length; m++) {
203
- count[candidates[m].group]++;
204
- }
205
-
206
- if (count[defNone] > 0) {
207
- defaultResult = defFalse;
208
- } else {
209
- defaultResult = defTrue;
210
- if ((count[defTrue] + count[defFalse]) > 1) {
211
- throw { type: 'Runtime',
212
- message: `Ambiguous use of \`default()\` found when matching for \`${this.format(args)}\``,
213
- index: this.getIndex(), filename: this.fileInfo().filename };
214
- }
215
- }
216
-
217
- for (m = 0; m < candidates.length; m++) {
218
- candidate = candidates[m].group;
219
- if ((candidate === defNone) || (candidate === defaultResult)) {
220
- try {
221
- mixin = candidates[m].mixin;
222
- if (!(mixin instanceof MixinDefinition)) {
223
- originalRuleset = /** @type {Node & { originalRuleset?: Node }} */ (mixin).originalRuleset || mixin;
224
- mixin = new MixinDefinition('', [], mixin.rules, null, false, null, originalRuleset.visibilityInfo());
225
- /** @type {Node & { originalRuleset?: Node }} */ (mixin).originalRuleset = originalRuleset;
226
- }
227
- const newRules = /** @type {MixinDefinition} */ (mixin).evalCall(context, args, this.important).rules;
228
- this._setVisibilityToReplacement(newRules);
229
- Array.prototype.push.apply(rules, newRules);
230
- } catch (e) {
231
- throw { .../** @type {object} */ (e), index: this.getIndex(), filename: this.fileInfo().filename };
232
- }
233
- }
234
- }
235
-
236
- if (match) {
237
- return /** @type {Node} */ (/** @type {unknown} */ (rules));
238
- }
239
- }
240
- }
241
- if (isOneFound) {
242
- throw { type: 'Runtime',
243
- message: `No matching definition was found for \`${this.format(args)}\``,
244
- index: this.getIndex(), filename: this.fileInfo().filename };
245
- } else {
246
- throw { type: 'Name',
247
- message: `${this.selector.toCSS(/** @type {EvalContext} */ ({})).trim()} is undefined`,
248
- index: this.getIndex(), filename: this.fileInfo().filename };
249
- }
250
- }
251
-
252
- /** @param {Node[]} replacement */
253
- _setVisibilityToReplacement(replacement) {
254
- /** @type {number} */
255
- let i;
256
- /** @type {Node} */
257
- let rule;
258
- if (this.blocksVisibility()) {
259
- for (i = 0; i < replacement.length; i++) {
260
- rule = replacement[i];
261
- rule.addVisibilityBlock();
262
- }
263
- }
264
- }
265
-
266
- /** @param {MixinArg[]} args */
267
- format(args) {
268
- return `${this.selector.toCSS(/** @type {EvalContext} */ ({})).trim()}(${args ? args.map(function (/** @type {MixinArg} */ a) {
269
- let argValue = '';
270
- if (a.name) {
271
- argValue += `${a.name}:`;
272
- }
273
- if (a.value.toCSS) {
274
- argValue += a.value.toCSS(/** @type {EvalContext} */ ({}));
275
- } else {
276
- argValue += '???';
277
- }
278
- return argValue;
279
- }).join(', ') : ''})`;
280
- }
281
- }
282
-
283
- export default MixinCall;
@@ -1,319 +0,0 @@
1
- // @ts-check
2
- /** @import { EvalContext, TreeVisitor, VisibilityInfo } from './node.js' */
3
- /** @import { FunctionRegistry } from './nested-at-rule.js' */
4
- /** @import { MixinArg } from './mixin-call.js' */
5
- import Node from './node.js';
6
- import Selector from './selector.js';
7
- import Element from './element.js';
8
- import Ruleset from './ruleset.js';
9
- import Declaration from './declaration.js';
10
- import DetachedRuleset from './detached-ruleset.js';
11
- import Expression from './expression.js';
12
- import contexts from '../contexts.js';
13
- import * as utils from '../utils.js';
14
-
15
- /**
16
- * @typedef {object} MixinParam
17
- * @property {string} [name]
18
- * @property {Node} [value]
19
- * @property {boolean} [variadic]
20
- */
21
-
22
- /**
23
- * @typedef {Ruleset & {
24
- * functionRegistry?: FunctionRegistry,
25
- * originalRuleset?: Node
26
- * }} RulesetWithRegistry
27
- */
28
-
29
- class Definition extends Ruleset {
30
- get type() { return 'MixinDefinition'; }
31
-
32
- /**
33
- * @param {string | undefined} name
34
- * @param {MixinParam[]} params
35
- * @param {Node[]} rules
36
- * @param {Node | null} [condition]
37
- * @param {boolean} [variadic]
38
- * @param {Node[] | null} [frames]
39
- * @param {VisibilityInfo} [visibilityInfo]
40
- */
41
- constructor(name, params, rules, condition, variadic, frames, visibilityInfo) {
42
- super(null, null);
43
- /** @type {string} */
44
- this.name = name || 'anonymous mixin';
45
- this.selectors = [new Selector([new Element(null, name, false, this._index, this._fileInfo)])];
46
- /** @type {MixinParam[]} */
47
- this.params = params;
48
- /** @type {Node | null | undefined} */
49
- this.condition = condition;
50
- /** @type {boolean | undefined} */
51
- this.variadic = variadic;
52
- /** @type {number} */
53
- this.arity = params.length;
54
- this.rules = rules;
55
- this._lookups = {};
56
- /** @type {string[]} */
57
- const optionalParameters = [];
58
- /** @type {number} */
59
- this.required = params.reduce(function (/** @type {number} */ count, /** @type {MixinParam} */ p) {
60
- if (!p.name || (p.name && !p.value)) {
61
- return count + 1;
62
- }
63
- else {
64
- optionalParameters.push(p.name);
65
- return count;
66
- }
67
- }, 0);
68
- /** @type {string[]} */
69
- this.optionalParameters = optionalParameters;
70
- /** @type {Node[] | null | undefined} */
71
- this.frames = frames;
72
- this.copyVisibilityInfo(visibilityInfo);
73
- this.allowRoot = true;
74
- /** @type {boolean} */
75
- this.evalFirst = true;
76
- }
77
-
78
- /** @param {TreeVisitor} visitor */
79
- accept(visitor) {
80
- if (this.params && this.params.length) {
81
- this.params = /** @type {MixinParam[]} */ (/** @type {unknown} */ (visitor.visitArray(/** @type {Node[]} */ (/** @type {unknown} */ (this.params)))));
82
- }
83
- this.rules = visitor.visitArray(this.rules);
84
- if (this.condition) {
85
- this.condition = visitor.visit(this.condition);
86
- }
87
- }
88
-
89
- /**
90
- * @param {EvalContext} context
91
- * @param {EvalContext} mixinEnv
92
- * @param {MixinArg[] | null} args
93
- * @param {Node[]} evaldArguments
94
- * @returns {Ruleset}
95
- */
96
- evalParams(context, mixinEnv, args, evaldArguments) {
97
- /* jshint boss:true */
98
- const frame = new Ruleset(null, null);
99
-
100
- /** @type {Node[] | undefined} */
101
- let varargs;
102
- /** @type {MixinArg | undefined} */
103
- let arg;
104
- const params = /** @type {MixinParam[]} */ (utils.copyArray(this.params));
105
- /** @type {number} */
106
- let i;
107
- /** @type {number} */
108
- let j;
109
- /** @type {Node | undefined} */
110
- let val;
111
- /** @type {string | undefined} */
112
- let name;
113
- /** @type {boolean} */
114
- let isNamedFound;
115
- /** @type {number} */
116
- let argIndex;
117
- let argsLength = 0;
118
-
119
- if (mixinEnv.frames && mixinEnv.frames[0] && /** @type {RulesetWithRegistry} */ (mixinEnv.frames[0]).functionRegistry) {
120
- /** @type {RulesetWithRegistry} */ (frame).functionRegistry = /** @type {FunctionRegistry} */ (/** @type {RulesetWithRegistry} */ (mixinEnv.frames[0]).functionRegistry).inherit();
121
- }
122
- mixinEnv = new contexts.Eval(mixinEnv, /** @type {Node[]} */ ([frame]).concat(/** @type {Node[]} */ (mixinEnv.frames)));
123
-
124
- if (args) {
125
- args = /** @type {MixinArg[]} */ (utils.copyArray(args));
126
- argsLength = args.length;
127
-
128
- for (i = 0; i < argsLength; i++) {
129
- arg = args[i];
130
- if (name = (arg && arg.name)) {
131
- isNamedFound = false;
132
- for (j = 0; j < params.length; j++) {
133
- if (!evaldArguments[j] && name === params[j].name) {
134
- evaldArguments[j] = arg.value.eval(context);
135
- frame.prependRule(new Declaration(name, arg.value.eval(context)));
136
- isNamedFound = true;
137
- break;
138
- }
139
- }
140
- if (isNamedFound) {
141
- args.splice(i, 1);
142
- i--;
143
- continue;
144
- } else {
145
- throw { type: 'Runtime', message: `Named argument for ${this.name} ${args[i].name} not found` };
146
- }
147
- }
148
- }
149
- }
150
- argIndex = 0;
151
- for (i = 0; i < params.length; i++) {
152
- if (evaldArguments[i]) { continue; }
153
-
154
- arg = args && args[argIndex];
155
-
156
- if (name = params[i].name) {
157
- if (params[i].variadic) {
158
- varargs = [];
159
- for (j = argIndex; j < argsLength; j++) {
160
- varargs.push(/** @type {MixinArg[]} */ (args)[j].value.eval(context));
161
- }
162
- frame.prependRule(new Declaration(name, new Expression(varargs).eval(context)));
163
- } else {
164
- val = arg && arg.value;
165
- if (val) {
166
- // This was a mixin call, pass in a detached ruleset of it's eval'd rules
167
- if (Array.isArray(val)) {
168
- val = /** @type {Node} */ (/** @type {unknown} */ (new DetachedRuleset(new Ruleset(null, /** @type {Node[]} */ (val)))));
169
- }
170
- else {
171
- val = val.eval(context);
172
- }
173
- } else if (params[i].value) {
174
- val = /** @type {Node} */ (params[i].value).eval(mixinEnv);
175
- frame.resetCache();
176
- } else {
177
- throw { type: 'Runtime', message: `wrong number of arguments for ${this.name} (${argsLength} for ${this.arity})` };
178
- }
179
-
180
- frame.prependRule(new Declaration(name, val));
181
- evaldArguments[i] = val;
182
- }
183
- }
184
-
185
- if (params[i].variadic && args) {
186
- for (j = argIndex; j < argsLength; j++) {
187
- evaldArguments[j] = args[j].value.eval(context);
188
- }
189
- }
190
- argIndex++;
191
- }
192
-
193
- return frame;
194
- }
195
-
196
- /** @returns {Ruleset} */
197
- makeImportant() {
198
- const rules = !this.rules ? this.rules : this.rules.map(function (/** @type {Node & { makeImportant?: (important?: boolean) => Node }} */ r) {
199
- if (r.makeImportant) {
200
- return r.makeImportant(true);
201
- } else {
202
- return r;
203
- }
204
- });
205
- const result = new Definition(this.name, this.params, rules, this.condition, this.variadic, this.frames);
206
- return /** @type {Ruleset} */ (/** @type {unknown} */ (result));
207
- }
208
-
209
- /**
210
- * @param {EvalContext} context
211
- * @returns {Definition}
212
- */
213
- eval(context) {
214
- return new Definition(this.name, this.params, this.rules, this.condition, this.variadic, this.frames || utils.copyArray(context.frames));
215
- }
216
-
217
- /**
218
- * @param {EvalContext} context
219
- * @param {MixinArg[]} args
220
- * @param {string | undefined} important
221
- * @returns {Ruleset}
222
- */
223
- evalCall(context, args, important) {
224
- /** @type {Node[]} */
225
- const _arguments = [];
226
- const mixinFrames = this.frames ? /** @type {Node[]} */ (this.frames).concat(/** @type {Node[]} */ (context.frames)) : /** @type {Node[]} */ (context.frames);
227
- const frame = this.evalParams(context, new contexts.Eval(context, mixinFrames), args, _arguments);
228
- /** @type {Node[]} */
229
- let rules;
230
- /** @type {Ruleset} */
231
- let ruleset;
232
-
233
- frame.prependRule(new Declaration('@arguments', new Expression(_arguments).eval(context)));
234
-
235
- rules = utils.copyArray(this.rules);
236
-
237
- ruleset = new Ruleset(null, rules);
238
- /** @type {RulesetWithRegistry} */ (ruleset).originalRuleset = this;
239
- ruleset = /** @type {Ruleset} */ (ruleset.eval(new contexts.Eval(context, /** @type {Node[]} */ ([this, frame]).concat(mixinFrames))));
240
- if (important) {
241
- ruleset = /** @type {Ruleset} */ (ruleset.makeImportant());
242
- }
243
- return ruleset;
244
- }
245
-
246
- /**
247
- * @param {MixinArg[] | null} args
248
- * @param {EvalContext} context
249
- * @returns {boolean}
250
- */
251
- matchCondition(args, context) {
252
- if (this.condition && !this.condition.eval(
253
- new contexts.Eval(context,
254
- /** @type {Node[]} */ ([this.evalParams(context, /* the parameter variables */
255
- new contexts.Eval(context, this.frames ? /** @type {Node[]} */ (this.frames).concat(/** @type {Node[]} */ (context.frames)) : context.frames), args, [])])
256
- .concat(/** @type {Node[]} */ (this.frames || [])) // the parent namespace/mixin frames
257
- .concat(/** @type {Node[]} */ (context.frames))))) { // the current environment frames
258
- return false;
259
- }
260
- return true;
261
- }
262
-
263
- /**
264
- * @param {MixinArg[] | null} args
265
- * @param {EvalContext} [context]
266
- * @returns {boolean}
267
- */
268
- matchArgs(args, context) {
269
- const allArgsCnt = (args && args.length) || 0;
270
- const evaldArguments = new Array(this.params.length);
271
- const positionalArgs = [];
272
- let positionalIndex = 0;
273
-
274
- for (let i = 0; i < allArgsCnt; i++) {
275
- const arg = /** @type {MixinArg[]} */ (args)[i];
276
- if (!arg.name) {
277
- positionalArgs.push(arg);
278
- continue;
279
- }
280
-
281
- const paramIndex = this.params.findIndex((param, index) => param.name === arg.name && !evaldArguments[index]);
282
- if (paramIndex < 0) {
283
- return false;
284
- }
285
- evaldArguments[paramIndex] = arg;
286
- }
287
-
288
- for (let i = 0; i < this.params.length; i++) {
289
- if (evaldArguments[i]) {
290
- continue;
291
- }
292
- if (this.params[i].variadic) {
293
- positionalIndex = positionalArgs.length;
294
- continue;
295
- }
296
- if (positionalIndex < positionalArgs.length) {
297
- evaldArguments[i] = positionalArgs[positionalIndex++];
298
- } else if (!this.params[i].name || !this.params[i].value) {
299
- return false;
300
- }
301
- }
302
-
303
- if (positionalIndex < positionalArgs.length) {
304
- return false;
305
- }
306
-
307
- // check patterns
308
- for (let i = 0; i < this.arity; i++) {
309
- if (!this.params[i].name && !this.params[i].variadic) {
310
- if (evaldArguments[i].value.eval(context).toCSS(/** @type {EvalContext} */ ({})) != /** @type {Node} */ (this.params[i].value).eval(context).toCSS(/** @type {EvalContext} */ ({}))) {
311
- return false;
312
- }
313
- }
314
- }
315
- return true;
316
- }
317
- }
318
-
319
- export default Definition;
@@ -1,95 +0,0 @@
1
- // @ts-check
2
- /** @import { EvalContext, FileInfo } from './node.js' */
3
- import Node from './node.js';
4
- import Variable from './variable.js';
5
- import Ruleset from './ruleset.js';
6
- import Selector from './selector.js';
7
-
8
- class NamespaceValue extends Node {
9
- get type() { return 'NamespaceValue'; }
10
-
11
- /**
12
- * @param {Node} ruleCall
13
- * @param {string[]} lookups
14
- * @param {number} index
15
- * @param {FileInfo} fileInfo
16
- */
17
- constructor(ruleCall, lookups, index, fileInfo) {
18
- super();
19
- this.value = ruleCall;
20
- this.lookups = lookups;
21
- this._index = index;
22
- this._fileInfo = fileInfo;
23
- }
24
-
25
- /**
26
- * @param {EvalContext} context
27
- * @returns {Node}
28
- */
29
- eval(context) {
30
- let i, name;
31
- /** @type {Ruleset | Node | Node[]} */
32
- let rules = this.value.eval(context);
33
-
34
- for (i = 0; i < this.lookups.length; i++) {
35
- name = this.lookups[i];
36
-
37
- if (Array.isArray(rules)) {
38
- rules = new Ruleset([new Selector()], rules);
39
- }
40
-
41
- const rs = /** @type {Ruleset} */ (rules);
42
-
43
- if (name === '') {
44
- rules = rs.lastDeclaration();
45
- }
46
- else if (name.charAt(0) === '@') {
47
- if (name.charAt(1) === '@') {
48
- name = `@${new Variable(name.slice(1)).eval(context).value}`;
49
- }
50
- if (rs.variables) {
51
- rules = rs.variable(name);
52
- }
53
-
54
- if (!rules) {
55
- throw { type: 'Name',
56
- message: `variable ${name} not found`,
57
- filename: this.fileInfo().filename,
58
- index: this.getIndex() };
59
- }
60
- }
61
- else {
62
- if (name.substring(0, 2) === '$@') {
63
- name = `$${new Variable(name.slice(1)).eval(context).value}`;
64
- }
65
- else {
66
- name = name.charAt(0) === '$' ? name : `$${name}`;
67
- }
68
- if (rs.properties) {
69
- rules = rs.property(name);
70
- }
71
-
72
- if (!rules) {
73
- throw { type: 'Name',
74
- message: `property "${name.slice(1)}" not found`,
75
- filename: this.fileInfo().filename,
76
- index: this.getIndex() };
77
- }
78
- const rulesArr = /** @type {Node[]} */ (rules);
79
- rules = rulesArr[rulesArr.length - 1];
80
- }
81
-
82
- const current = /** @type {Node} */ (rules);
83
- if (current.value) {
84
- rules = /** @type {Node} */ (current.eval(context).value);
85
- }
86
- const currentNode = /** @type {Node & { ruleset?: Node }} */ (rules);
87
- if (currentNode.ruleset) {
88
- rules = currentNode.ruleset.eval(context);
89
- }
90
- }
91
- return /** @type {Node} */ (rules);
92
- }
93
- }
94
-
95
- export default NamespaceValue;