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,158 +0,0 @@
1
- import Comment from '../tree/comment.js';
2
- import Node from '../tree/node.js';
3
- import Dimension from '../tree/dimension.js';
4
- import Declaration from '../tree/declaration.js';
5
- import Expression from '../tree/expression.js';
6
- import Ruleset from '../tree/ruleset.js';
7
- import Selector from '../tree/selector.js';
8
- import Element from '../tree/element.js';
9
- import Quote from '../tree/quoted.js';
10
- import Value from '../tree/value.js';
11
-
12
- const getItemsFromNode = node => {
13
- // handle non-array values as an array of length 1
14
- // return 'undefined' if index is invalid
15
- const items = Array.isArray(node.value) ?
16
- node.value : Array(node);
17
-
18
- return items;
19
- };
20
-
21
- export default {
22
- _SELF: function(n) {
23
- return n;
24
- },
25
- '~': function(...expr) {
26
- if (expr.length === 1) {
27
- return expr[0];
28
- }
29
- return new Value(expr);
30
- },
31
- extract: function(values, index) {
32
- // (1-based index)
33
- index = index.value - 1;
34
-
35
- return getItemsFromNode(values)[index];
36
- },
37
- length: function(values) {
38
- return new Dimension(getItemsFromNode(values).length);
39
- },
40
- /**
41
- * Creates a Less list of incremental values.
42
- * Modeled after Lodash's range function, also exists natively in PHP
43
- *
44
- * @param {Dimension} [start=1]
45
- * @param {Dimension} end - e.g. 10 or 10px - unit is added to output
46
- * @param {Dimension} [step=1]
47
- */
48
- range: function(start, end, step) {
49
- let from;
50
- let to;
51
- let stepValue = 1;
52
- const list = [];
53
- if (end) {
54
- to = end;
55
- from = start.value;
56
- if (step) {
57
- stepValue = step.value;
58
- }
59
- }
60
- else {
61
- from = 1;
62
- to = start;
63
- }
64
-
65
- for (let i = from; i <= to.value; i += stepValue) {
66
- list.push(new Dimension(i, to.unit));
67
- }
68
-
69
- return new Expression(list);
70
- },
71
- each: function(list, rs) {
72
- const rules = [];
73
- let newRules;
74
- let iterator;
75
-
76
- const tryEval = val => {
77
- if (val instanceof Node) {
78
- return val.eval(this.context);
79
- }
80
- return val;
81
- };
82
-
83
- if (list.value && !(list instanceof Quote)) {
84
- if (Array.isArray(list.value)) {
85
- iterator = list.value.map(tryEval);
86
- } else {
87
- iterator = [tryEval(list.value)];
88
- }
89
- } else if (list.ruleset) {
90
- iterator = tryEval(list.ruleset).rules;
91
- } else if (list.rules) {
92
- iterator = list.rules.map(tryEval);
93
- } else if (Array.isArray(list)) {
94
- iterator = list.map(tryEval);
95
- } else {
96
- iterator = [tryEval(list)];
97
- }
98
-
99
- let valueName = '@value';
100
- let keyName = '@key';
101
- let indexName = '@index';
102
-
103
- if (rs.params) {
104
- valueName = rs.params[0] && rs.params[0].name;
105
- keyName = rs.params[1] && rs.params[1].name;
106
- indexName = rs.params[2] && rs.params[2].name;
107
- rs = rs.rules;
108
- } else {
109
- rs = rs.ruleset;
110
- }
111
-
112
- for (let i = 0; i < iterator.length; i++) {
113
- let key;
114
- let value;
115
- const item = iterator[i];
116
- if (item instanceof Declaration) {
117
- key = typeof item.name === 'string' ? item.name : item.name[0].value;
118
- value = item.value;
119
- } else {
120
- key = new Dimension(i + 1);
121
- value = item;
122
- }
123
-
124
- if (item instanceof Comment) {
125
- continue;
126
- }
127
-
128
- newRules = rs.rules.slice(0);
129
- if (valueName) {
130
- newRules.push(new Declaration(valueName,
131
- value,
132
- false, false, this.index, this.currentFileInfo));
133
- }
134
- if (indexName) {
135
- newRules.push(new Declaration(indexName,
136
- new Dimension(i + 1),
137
- false, false, this.index, this.currentFileInfo));
138
- }
139
- if (keyName) {
140
- newRules.push(new Declaration(keyName,
141
- key,
142
- false, false, this.index, this.currentFileInfo));
143
- }
144
-
145
- rules.push(new Ruleset([ new(Selector)([ new Element('', '&') ]) ],
146
- newRules,
147
- rs.strictImports,
148
- rs.visibilityInfo()
149
- ));
150
- }
151
-
152
- return new Ruleset([ new(Selector)([ new Element('', '&') ]) ],
153
- rules,
154
- rs.strictImports,
155
- rs.visibilityInfo()
156
- ).eval(this.context);
157
- }
158
- };
@@ -1,22 +0,0 @@
1
- import Dimension from '../tree/dimension.js';
2
-
3
- const MathHelper = (fn, unit, cssEvaluable, n) => {
4
- if (!(n instanceof Dimension)) {
5
- // A runtime CSS value such as var()/env() stays an unevaluated call and
6
- // cannot be resolved to a number at compile time. Only functions with a
7
- // CSS equivalent may be left for the browser; the rest (percentage, ceil,
8
- // floor, round) have no CSS form and keep erroring on such input.
9
- if (cssEvaluable && n && n.type === 'Call') {
10
- return undefined;
11
- }
12
- throw { type: 'Argument', message: 'argument must be a number' };
13
- }
14
- if (unit === null) {
15
- unit = n.unit;
16
- } else {
17
- n = n.unify();
18
- }
19
- return new Dimension(fn(parseFloat(n.value)), unit);
20
- };
21
-
22
- export default MathHelper;
@@ -1,30 +0,0 @@
1
- import mathHelper from './math-helper.js';
2
-
3
- const mathFunctions = {
4
- // name: [unit, has a CSS equivalent that the browser can evaluate]
5
- ceil: [null, false],
6
- floor: [null, false],
7
- sqrt: [null, true],
8
- abs: [null, true],
9
- tan: ['', true],
10
- sin: ['', true],
11
- cos: ['', true],
12
- atan: ['rad', true],
13
- asin: ['rad', true],
14
- acos: ['rad', true]
15
- };
16
-
17
- for (const f in mathFunctions) {
18
- // eslint-disable-next-line no-prototype-builtins
19
- if (mathFunctions.hasOwnProperty(f)) {
20
- const [unit, cssEvaluable] = mathFunctions[f];
21
- mathFunctions[f] = mathHelper.bind(null, Math[f], unit, cssEvaluable);
22
- }
23
- }
24
-
25
- mathFunctions.round = (n, f) => {
26
- const fraction = typeof f === 'undefined' ? 0 : f.value;
27
- return mathHelper(num => num.toFixed(fraction), null, false, n);
28
- };
29
-
30
- export default mathFunctions;
@@ -1,95 +0,0 @@
1
- import Dimension from '../tree/dimension.js';
2
- import Anonymous from '../tree/anonymous.js';
3
- import mathHelper from './math-helper.js';
4
-
5
- const minMax = function (isMin, args) {
6
- args = Array.prototype.slice.call(args);
7
- switch (args.length) {
8
- case 0: throw { type: 'Argument', message: 'one or more arguments required' };
9
- }
10
- let i; // key is the unit.toString() for unified Dimension values,
11
- let j;
12
- let current;
13
- let currentUnified;
14
- let referenceUnified;
15
- let unit;
16
- let unitStatic;
17
- let unitClone;
18
-
19
- const // elems only contains original argument values.
20
- order = [];
21
-
22
- const values = {};
23
- // value is the index into the order array.
24
- for (i = 0; i < args.length; i++) {
25
- current = args[i];
26
- if (!(current instanceof Dimension)) {
27
- if (Array.isArray(args[i].value)) {
28
- Array.prototype.push.apply(args, Array.prototype.slice.call(args[i].value));
29
- continue;
30
- } else {
31
- throw { type: 'Argument', message: 'incompatible types' };
32
- }
33
- }
34
- currentUnified = current.unit.toString() === '' && unitClone !== undefined ? new Dimension(current.value, unitClone).unify() : current.unify();
35
- unit = currentUnified.unit.toString() === '' && unitStatic !== undefined ? unitStatic : currentUnified.unit.toString();
36
- unitStatic = unit !== '' && unitStatic === undefined || unit !== '' && order[0].unify().unit.toString() === '' ? unit : unitStatic;
37
- unitClone = unit !== '' && unitClone === undefined ? current.unit.toString() : unitClone;
38
- j = values[''] !== undefined && unit !== '' && unit === unitStatic ? values[''] : values[unit];
39
- if (j === undefined) {
40
- if (unitStatic !== undefined && unit !== unitStatic) {
41
- throw { type: 'Argument', message: 'incompatible types' };
42
- }
43
- values[unit] = order.length;
44
- order.push(current);
45
- continue;
46
- }
47
- referenceUnified = order[j].unit.toString() === '' && unitClone !== undefined ? new Dimension(order[j].value, unitClone).unify() : order[j].unify();
48
- if ( isMin && currentUnified.value < referenceUnified.value ||
49
- !isMin && currentUnified.value > referenceUnified.value) {
50
- order[j] = current;
51
- }
52
- }
53
- if (order.length == 1) {
54
- return order[0];
55
- }
56
- args = order.map(a => { return a.toCSS(this.context); }).join(this.context.compress ? ',' : ', ');
57
- return new Anonymous(`${isMin ? 'min' : 'max'}(${args})`);
58
- };
59
-
60
- export default {
61
- min: function(...args) {
62
- try {
63
- return minMax.call(this, true, args);
64
- } catch (e) {}
65
- },
66
- max: function(...args) {
67
- try {
68
- return minMax.call(this, false, args);
69
- } catch (e) {}
70
- },
71
- convert: function (val, unit) {
72
- return val.convertTo(unit.value);
73
- },
74
- pi: function () {
75
- return new Dimension(Math.PI);
76
- },
77
- mod: function(a, b) {
78
- return new Dimension(a.value % b.value, a.unit);
79
- },
80
- pow: function(x, y) {
81
- if (typeof x === 'number' && typeof y === 'number') {
82
- x = new Dimension(x);
83
- y = new Dimension(y);
84
- } else if (!(x instanceof Dimension) || !(y instanceof Dimension)) {
85
- throw { type: 'Argument', message: 'arguments must be numbers' };
86
- }
87
-
88
- return new Dimension(Math.pow(x.value, y.value), x.unit);
89
- },
90
- percentage: function (n) {
91
- const result = mathHelper(num => num * 100, '%', false, n);
92
-
93
- return result;
94
- }
95
- };
@@ -1,36 +0,0 @@
1
- import Quoted from '../tree/quoted.js';
2
- import Anonymous from '../tree/anonymous.js';
3
- import JavaScript from '../tree/javascript.js';
4
-
5
- export default {
6
- e: function (str) {
7
- return new Quoted('"', str instanceof JavaScript ? str.evaluated : str.value, true);
8
- },
9
- escape: function (str) {
10
- return new Anonymous(
11
- encodeURI(str.value).replace(/=/g, '%3D').replace(/:/g, '%3A').replace(/#/g, '%23').replace(/;/g, '%3B')
12
- .replace(/\(/g, '%28').replace(/\)/g, '%29'));
13
- },
14
- replace: function (string, pattern, replacement, flags) {
15
- let result = string.value;
16
- replacement = (replacement.type === 'Quoted') ?
17
- replacement.value : replacement.toCSS();
18
- result = result.replace(new RegExp(pattern.value, flags ? flags.value : ''), replacement);
19
- return new Quoted(string.quote || '', result, string.escaped);
20
- },
21
- '%': function (string /* arg, arg, ... */) {
22
- const args = Array.prototype.slice.call(arguments, 1);
23
- let result = string.value;
24
-
25
- for (let i = 0; i < args.length; i++) {
26
- /* jshint loopfunc:true */
27
- result = result.replace(/%[sda]/i, token => {
28
- const value = ((args[i].type === 'Quoted') &&
29
- token.match(/s/i)) ? args[i].value : args[i].toCSS();
30
- return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
31
- });
32
- }
33
- result = result.replace(/%%/g, '%');
34
- return new Quoted(string.quote || '', result, string.escaped);
35
- }
36
- };
@@ -1,29 +0,0 @@
1
- import Variable from '../tree/variable.js';
2
- import Anonymous from '../tree/anonymous.js';
3
-
4
- /** @param {*[]} args */
5
- const styleExpression = function (args) {
6
- args = Array.prototype.slice.call(args);
7
- if (args.length === 0) {
8
- throw { type: 'Argument', message: 'one or more arguments required' };
9
- }
10
-
11
- const entityList = [new Variable(args[0].value, this.index, this.currentFileInfo).eval(this.context)];
12
-
13
- const result = entityList.map(a => { return a.toCSS(this.context); }).join(this.context.compress ? ',' : ', ');
14
-
15
- return new Anonymous(`style(${result})`);
16
- };
17
-
18
- export default {
19
- /** @param {...*} args */
20
- style: function(...args) {
21
- try {
22
- return styleExpression.call(this, args);
23
- } catch (e) {
24
- // When style() is used as a CSS function (e.g. @container style(--responsive: true)),
25
- // arguments won't be valid Less variables. Return undefined to let the
26
- // parser fall through and treat it as plain CSS.
27
- }
28
- },
29
- };
@@ -1,87 +0,0 @@
1
- import Dimension from '../tree/dimension.js';
2
- import Color from '../tree/color.js';
3
- import Expression from '../tree/expression.js';
4
- import Quoted from '../tree/quoted.js';
5
- import URL from '../tree/url.js';
6
-
7
- export default () => {
8
- return { 'svg-gradient': function(direction) {
9
- let stops;
10
- let gradientDirectionSvg;
11
- let gradientType = 'linear';
12
- let rectangleDimension = 'x="0" y="0" width="1" height="1"';
13
- const renderEnv = {compress: false};
14
- let returner;
15
- const directionValue = direction.toCSS(renderEnv);
16
- let i;
17
- let color;
18
- let position;
19
- let positionValue;
20
- let alpha;
21
-
22
- function throwArgumentDescriptor() {
23
- throw { type: 'Argument',
24
- message: 'svg-gradient expects direction, start_color [start_position], [color position,]...,' +
25
- ' end_color [end_position] or direction, color list' };
26
- }
27
-
28
- if (arguments.length == 2) {
29
- if (arguments[1].value.length < 2) {
30
- throwArgumentDescriptor();
31
- }
32
- stops = arguments[1].value;
33
- } else if (arguments.length < 3) {
34
- throwArgumentDescriptor();
35
- } else {
36
- stops = Array.prototype.slice.call(arguments, 1);
37
- }
38
-
39
- switch (directionValue) {
40
- case 'to bottom':
41
- gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"';
42
- break;
43
- case 'to right':
44
- gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="0%"';
45
- break;
46
- case 'to bottom right':
47
- gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="100%"';
48
- break;
49
- case 'to top right':
50
- gradientDirectionSvg = 'x1="0%" y1="100%" x2="100%" y2="0%"';
51
- break;
52
- case 'ellipse':
53
- case 'ellipse at center':
54
- gradientType = 'radial';
55
- gradientDirectionSvg = 'cx="50%" cy="50%" r="75%"';
56
- rectangleDimension = 'x="-50" y="-50" width="101" height="101"';
57
- break;
58
- default:
59
- throw { type: 'Argument', message: 'svg-gradient direction must be \'to bottom\', \'to right\',' +
60
- ' \'to bottom right\', \'to top right\' or \'ellipse at center\'' };
61
- }
62
- returner = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1 1"><${gradientType}Gradient id="g" ${gradientDirectionSvg}>`;
63
-
64
- for (i = 0; i < stops.length; i += 1) {
65
- if (stops[i] instanceof Expression) {
66
- color = stops[i].value[0];
67
- position = stops[i].value[1];
68
- } else {
69
- color = stops[i];
70
- position = undefined;
71
- }
72
-
73
- if (!(color instanceof Color) || (!((i === 0 || i + 1 === stops.length) && position === undefined) && !(position instanceof Dimension))) {
74
- throwArgumentDescriptor();
75
- }
76
- positionValue = position ? position.toCSS(renderEnv) : i === 0 ? '0%' : '100%';
77
- alpha = color.alpha;
78
- returner += `<stop offset="${positionValue}" stop-color="${color.toRGB()}"${alpha < 1 ? ` stop-opacity="${alpha}"` : ''}/>`;
79
- }
80
- returner += `</${gradientType}Gradient><rect ${rectangleDimension} fill="url(#g)" /></svg>`;
81
-
82
- returner = encodeURIComponent(returner);
83
-
84
- returner = `data:image/svg+xml,${returner}`;
85
- return new URL(new Quoted(`'${returner}'`, returner, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo);
86
- }};
87
- };
@@ -1,70 +0,0 @@
1
- import Keyword from '../tree/keyword.js';
2
- import DetachedRuleset from '../tree/detached-ruleset.js';
3
- import Dimension from '../tree/dimension.js';
4
- import Color from '../tree/color.js';
5
- import Quoted from '../tree/quoted.js';
6
- import Anonymous from '../tree/anonymous.js';
7
- import URL from '../tree/url.js';
8
- import Operation from '../tree/operation.js';
9
-
10
- const isa = (n, Type) => (n instanceof Type) ? Keyword.True : Keyword.False;
11
- const isunit = (n, unit) => {
12
- if (unit === undefined) {
13
- throw { type: 'Argument', message: 'missing the required second argument to isunit.' };
14
- }
15
- unit = typeof unit.value === 'string' ? unit.value : unit;
16
- if (typeof unit !== 'string') {
17
- throw { type: 'Argument', message: 'Second argument to isunit should be a unit or a string.' };
18
- }
19
- return (n instanceof Dimension) && n.unit.is(unit) ? Keyword.True : Keyword.False;
20
- };
21
-
22
- export default {
23
- isruleset: function (n) {
24
- return isa(n, DetachedRuleset);
25
- },
26
- iscolor: function (n) {
27
- return isa(n, Color);
28
- },
29
- isnumber: function (n) {
30
- return isa(n, Dimension);
31
- },
32
- isstring: function (n) {
33
- return isa(n, Quoted);
34
- },
35
- iskeyword: function (n) {
36
- return isa(n, Keyword);
37
- },
38
- isurl: function (n) {
39
- return isa(n, URL);
40
- },
41
- ispixel: function (n) {
42
- return isunit(n, 'px');
43
- },
44
- ispercentage: function (n) {
45
- return isunit(n, '%');
46
- },
47
- isem: function (n) {
48
- return isunit(n, 'em');
49
- },
50
- isunit,
51
- unit: function (val, unit) {
52
- if (!(val instanceof Dimension)) {
53
- throw { type: 'Argument',
54
- message: `the first argument to unit must be a number${val instanceof Operation ? '. Have you forgotten parenthesis?' : ''}` };
55
- }
56
- if (unit) {
57
- if (unit instanceof Keyword) {
58
- unit = unit.value;
59
- } else {
60
- unit = unit.toCSS();
61
- }
62
- } else {
63
- unit = '';
64
- }
65
- return new Dimension(val.value, unit);
66
- },
67
- 'get-unit': function (n) {
68
- return new Anonymous(n.unit);
69
- }
70
- };