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,139 +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
- if (!this.variable && evaldValue.type === 'DetachedRuleset') {
99
- throw { message: 'Rulesets cannot be evaluated on a property.',
100
- index: this.getIndex(), filename: this.fileInfo().filename };
101
- }
102
- let important = this.important;
103
- const importantResult = context.importantScope.pop();
104
- if (!important && importantResult && importantResult.important) {
105
- important = importantResult.important;
106
- }
107
-
108
- return new Declaration(/** @type {string} */ (name),
109
- evaldValue,
110
- important,
111
- this.merge,
112
- this.getIndex(), this.fileInfo(), this.inline,
113
- variable);
114
- }
115
- catch (e) {
116
- const err = /** @type {{ index?: number, filename?: string }} */ (e);
117
- if (typeof err.index !== 'number') {
118
- err.index = this.getIndex();
119
- err.filename = this.fileInfo().filename;
120
- }
121
- throw e;
122
- }
123
- finally {
124
- if (mathBypass) {
125
- context.math = prevMath;
126
- }
127
- }
128
- }
129
-
130
- makeImportant() {
131
- return new Declaration(this.name,
132
- /** @type {Node} */ (this.value),
133
- '!important',
134
- this.merge,
135
- this.getIndex(), this.fileInfo(), this.inline);
136
- }
137
- }
138
-
139
- 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;