less 3.10.0-beta.2 → 3.10.3
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.
- package/.DS_Store +0 -0
- package/bin/lessc +6652 -5505
- package/dist/less.cjs.js +6593 -5448
- package/dist/less.js +10 -6
- package/dist/less.min.js +2 -2
- package/dist/less.min.js.map +1 -1
- package/lib/less/constants.js +13 -0
- package/lib/less/contexts.js +164 -0
- package/lib/less/data/colors.js +150 -0
- package/lib/less/data/index.js +4 -0
- package/lib/less/data/unit-conversions.js +21 -0
- package/lib/less/default-options.js +68 -0
- package/lib/less/environment/abstract-file-manager.js +127 -0
- package/lib/less/environment/abstract-plugin-loader.js +187 -0
- package/lib/less/environment/environment-api.js +25 -0
- package/lib/less/environment/environment.js +59 -0
- package/lib/less/environment/file-manager-api.js +103 -0
- package/lib/less/functions/boolean.js +13 -0
- package/lib/less/functions/color-blending.js +84 -0
- package/lib/less/functions/color.js +417 -0
- package/lib/less/functions/data-uri.js +74 -0
- package/lib/less/functions/default.js +25 -0
- package/lib/less/functions/function-caller.js +49 -0
- package/lib/less/functions/function-registry.js +35 -0
- package/lib/less/functions/index.js +33 -0
- package/lib/less/functions/list.js +143 -0
- package/lib/less/functions/math-helper.js +15 -0
- package/lib/less/functions/math.js +28 -0
- package/lib/less/functions/number.js +89 -0
- package/lib/less/functions/string.js +36 -0
- package/lib/less/functions/svg.js +87 -0
- package/lib/less/functions/types.js +70 -0
- package/lib/less/import-manager.js +169 -0
- package/lib/less/index.js +92 -0
- package/lib/less/less-error.js +140 -0
- package/lib/less/logger.js +34 -0
- package/lib/less/parse-tree.js +66 -0
- package/lib/less/parse.js +89 -0
- package/lib/less/parser/chunker.js +122 -0
- package/lib/less/parser/parser-input.js +390 -0
- package/lib/less/parser/parser.js +2418 -0
- package/lib/less/plugin-manager.js +168 -0
- package/lib/less/render.js +42 -0
- package/lib/less/source-map-builder.js +77 -0
- package/lib/less/source-map-output.js +149 -0
- package/lib/less/transform-tree.js +96 -0
- package/lib/less/tree/anonymous.js +37 -0
- package/lib/less/tree/assignment.js +33 -0
- package/lib/less/tree/atrule.js +165 -0
- package/lib/less/tree/attribute.js +34 -0
- package/lib/less/tree/call.js +105 -0
- package/lib/less/tree/color.js +246 -0
- package/lib/less/tree/combinator.js +29 -0
- package/lib/less/tree/comment.js +29 -0
- package/lib/less/tree/condition.js +43 -0
- package/lib/less/tree/debug-info.js +34 -0
- package/lib/less/tree/declaration.js +115 -0
- package/lib/less/tree/detached-ruleset.js +30 -0
- package/lib/less/tree/dimension.js +179 -0
- package/lib/less/tree/element.js +73 -0
- package/lib/less/tree/expression.js +74 -0
- package/lib/less/tree/extend.js +66 -0
- package/lib/less/tree/import.js +184 -0
- package/lib/less/tree/index.js +54 -0
- package/lib/less/tree/javascript.js +33 -0
- package/lib/less/tree/js-eval-node.js +58 -0
- package/lib/less/tree/keyword.js +21 -0
- package/lib/less/tree/media.js +154 -0
- package/lib/less/tree/mixin-call.js +215 -0
- package/lib/less/tree/mixin-definition.js +229 -0
- package/lib/less/tree/namespace-value.js +87 -0
- package/lib/less/tree/negative.js +26 -0
- package/lib/less/tree/node.js +178 -0
- package/lib/less/tree/operation.js +62 -0
- package/lib/less/tree/paren.js +22 -0
- package/lib/less/tree/property.js +77 -0
- package/lib/less/tree/quoted.js +70 -0
- package/lib/less/tree/ruleset.js +867 -0
- package/lib/less/tree/selector.js +146 -0
- package/lib/less/tree/unicode-descriptor.js +13 -0
- package/lib/less/tree/unit.js +141 -0
- package/lib/less/tree/url.js +65 -0
- package/lib/less/tree/value.js +44 -0
- package/lib/less/tree/variable-call.js +46 -0
- package/lib/less/tree/variable.js +67 -0
- package/lib/less/utils.js +122 -0
- package/lib/less/visitors/extend-visitor.js +505 -0
- package/lib/less/visitors/import-sequencer.js +58 -0
- package/lib/less/visitors/import-visitor.js +189 -0
- package/lib/less/visitors/index.js +15 -0
- package/lib/less/visitors/join-selector-visitor.js +57 -0
- package/lib/less/visitors/set-tree-visibility-visitor.js +45 -0
- package/lib/less/visitors/to-css-visitor.js +363 -0
- package/lib/less/visitors/visitor.js +163 -0
- package/lib/less-browser/add-default-options.js +49 -0
- package/lib/less-browser/bootstrap.js +69 -0
- package/lib/less-browser/browser.js +65 -0
- package/lib/less-browser/cache.js +43 -0
- package/lib/less-browser/error-reporting.js +170 -0
- package/lib/less-browser/file-manager.js +113 -0
- package/lib/less-browser/image-size.js +28 -0
- package/lib/less-browser/index.js +285 -0
- package/lib/less-browser/log-listener.js +42 -0
- package/lib/less-browser/plugin-loader.js +26 -0
- package/lib/less-browser/utils.js +24 -0
- package/lib/less-node/environment.js +16 -0
- package/lib/less-node/file-manager.js +177 -0
- package/lib/less-node/fs.js +10 -0
- package/lib/less-node/image-size.js +58 -0
- package/lib/less-node/index.js +27 -0
- package/lib/less-node/lessc-helper.js +89 -0
- package/lib/less-node/plugin-loader.js +53 -0
- package/lib/less-node/url-file-manager.js +49 -0
- package/lib/lessc.js +557 -0
- package/lib/source-map/source-map-0.1.31.js +1933 -0
- package/lib/source-map/source-map-footer.js +4 -0
- package/lib/source-map/source-map-header.js +3 -0
- package/package.json +1 -1
- package/test/.DS_Store +0 -0
- package/test/browser/less.min.js +11 -0
- package/test/browser/less.min.js.map +1 -0
- package/test/css/css-escapes.css +1 -0
- package/test/less/css-escapes.less +3 -1
- package/.git/index +0 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import Node from './node';
|
|
2
|
+
import Value from './value';
|
|
3
|
+
import Keyword from './keyword';
|
|
4
|
+
import Anonymous from './anonymous';
|
|
5
|
+
import * as Constants from '../constants';
|
|
6
|
+
const MATH = Constants.Math;
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Declaration extends Node {
|
|
10
|
+
constructor(name, value, important, merge, index, currentFileInfo, inline, variable) {
|
|
11
|
+
super();
|
|
12
|
+
|
|
13
|
+
this.name = name;
|
|
14
|
+
this.value = (value instanceof Node) ? value : new Value([value ? new Anonymous(value) : null]);
|
|
15
|
+
this.important = important ? ` ${important.trim()}` : '';
|
|
16
|
+
this.merge = merge;
|
|
17
|
+
this._index = index;
|
|
18
|
+
this._fileInfo = currentFileInfo;
|
|
19
|
+
this.inline = inline || false;
|
|
20
|
+
this.variable = (variable !== undefined) ? variable
|
|
21
|
+
: (name.charAt && (name.charAt(0) === '@'));
|
|
22
|
+
this.allowRoot = true;
|
|
23
|
+
this.setParent(this.value, this);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
genCSS(context, output) {
|
|
27
|
+
output.add(this.name + (context.compress ? ':' : ': '), this.fileInfo(), this.getIndex());
|
|
28
|
+
try {
|
|
29
|
+
this.value.genCSS(context, output);
|
|
30
|
+
}
|
|
31
|
+
catch (e) {
|
|
32
|
+
e.index = this._index;
|
|
33
|
+
e.filename = this._fileInfo.filename;
|
|
34
|
+
throw e;
|
|
35
|
+
}
|
|
36
|
+
output.add(this.important + ((this.inline || (context.lastRule && context.compress)) ? '' : ';'), this._fileInfo, this._index);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
eval(context) {
|
|
40
|
+
let mathBypass = false;
|
|
41
|
+
let prevMath;
|
|
42
|
+
let name = this.name;
|
|
43
|
+
let evaldValue;
|
|
44
|
+
let variable = this.variable;
|
|
45
|
+
if (typeof name !== 'string') {
|
|
46
|
+
// expand 'primitive' name directly to get
|
|
47
|
+
// things faster (~10% for benchmark.less):
|
|
48
|
+
name = (name.length === 1) && (name[0] instanceof Keyword) ?
|
|
49
|
+
name[0].value : evalName(context, name);
|
|
50
|
+
variable = false; // never treat expanded interpolation as new variable name
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// @todo remove when parens-division is default
|
|
54
|
+
if (name === 'font' && context.math === MATH.ALWAYS) {
|
|
55
|
+
mathBypass = true;
|
|
56
|
+
prevMath = context.math;
|
|
57
|
+
context.math = MATH.PARENS_DIVISION;
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
context.importantScope.push({});
|
|
61
|
+
evaldValue = this.value.eval(context);
|
|
62
|
+
|
|
63
|
+
if (!this.variable && evaldValue.type === 'DetachedRuleset') {
|
|
64
|
+
throw { message: 'Rulesets cannot be evaluated on a property.',
|
|
65
|
+
index: this.getIndex(), filename: this.fileInfo().filename };
|
|
66
|
+
}
|
|
67
|
+
let important = this.important;
|
|
68
|
+
const importantResult = context.importantScope.pop();
|
|
69
|
+
if (!important && importantResult.important) {
|
|
70
|
+
important = importantResult.important;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return new Declaration(name,
|
|
74
|
+
evaldValue,
|
|
75
|
+
important,
|
|
76
|
+
this.merge,
|
|
77
|
+
this.getIndex(), this.fileInfo(), this.inline,
|
|
78
|
+
variable);
|
|
79
|
+
}
|
|
80
|
+
catch (e) {
|
|
81
|
+
if (typeof e.index !== 'number') {
|
|
82
|
+
e.index = this.getIndex();
|
|
83
|
+
e.filename = this.fileInfo().filename;
|
|
84
|
+
}
|
|
85
|
+
throw e;
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
if (mathBypass) {
|
|
89
|
+
context.math = prevMath;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
makeImportant() {
|
|
95
|
+
return new Declaration(this.name,
|
|
96
|
+
this.value,
|
|
97
|
+
'!important',
|
|
98
|
+
this.merge,
|
|
99
|
+
this.getIndex(), this.fileInfo(), this.inline);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function evalName(context, name) {
|
|
104
|
+
let value = '';
|
|
105
|
+
let i;
|
|
106
|
+
const n = name.length;
|
|
107
|
+
const output = {add: function (s) {value += s;}};
|
|
108
|
+
for (i = 0; i < n; i++) {
|
|
109
|
+
name[i].eval(context).genCSS(context, output);
|
|
110
|
+
}
|
|
111
|
+
return value;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
Declaration.prototype.type = 'Declaration';
|
|
115
|
+
export default Declaration;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import Node from './node';
|
|
2
|
+
import contexts from '../contexts';
|
|
3
|
+
import * as utils from '../utils';
|
|
4
|
+
|
|
5
|
+
class DetachedRuleset extends Node {
|
|
6
|
+
constructor(ruleset, frames) {
|
|
7
|
+
super();
|
|
8
|
+
|
|
9
|
+
this.ruleset = ruleset;
|
|
10
|
+
this.frames = frames;
|
|
11
|
+
this.setParent(this.ruleset, this);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
accept(visitor) {
|
|
15
|
+
this.ruleset = visitor.visit(this.ruleset);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
eval(context) {
|
|
19
|
+
const frames = this.frames || utils.copyArray(context.frames);
|
|
20
|
+
return new DetachedRuleset(this.ruleset, frames);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
callEval(context) {
|
|
24
|
+
return this.ruleset.eval(this.frames ? new contexts.Eval(context, this.frames.concat(context.frames)) : context);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
DetachedRuleset.prototype.type = 'DetachedRuleset';
|
|
29
|
+
DetachedRuleset.prototype.evalFirst = true;
|
|
30
|
+
export default DetachedRuleset;
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import Node from './node';
|
|
2
|
+
import unitConversions from '../data/unit-conversions';
|
|
3
|
+
import Unit from './unit';
|
|
4
|
+
import Color from './color';
|
|
5
|
+
|
|
6
|
+
//
|
|
7
|
+
// A number with a unit
|
|
8
|
+
//
|
|
9
|
+
class Dimension extends Node {
|
|
10
|
+
constructor(value, unit) {
|
|
11
|
+
super();
|
|
12
|
+
|
|
13
|
+
this.value = parseFloat(value);
|
|
14
|
+
if (isNaN(this.value)) {
|
|
15
|
+
throw new Error('Dimension is not a number.');
|
|
16
|
+
}
|
|
17
|
+
this.unit = (unit && unit instanceof Unit) ? unit :
|
|
18
|
+
new Unit(unit ? [unit] : undefined);
|
|
19
|
+
this.setParent(this.unit, this);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
accept(visitor) {
|
|
23
|
+
this.unit = visitor.visit(this.unit);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
eval(context) {
|
|
27
|
+
return this;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
toColor() {
|
|
31
|
+
return new Color([this.value, this.value, this.value]);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
genCSS(context, output) {
|
|
35
|
+
if ((context && context.strictUnits) && !this.unit.isSingular()) {
|
|
36
|
+
throw new Error(`Multiple units in dimension. Correct the units or use the unit function. Bad unit: ${this.unit.toString()}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const value = this.fround(context, this.value);
|
|
40
|
+
let strValue = String(value);
|
|
41
|
+
|
|
42
|
+
if (value !== 0 && value < 0.000001 && value > -0.000001) {
|
|
43
|
+
// would be output 1e-6 etc.
|
|
44
|
+
strValue = value.toFixed(20).replace(/0+$/, '');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (context && context.compress) {
|
|
48
|
+
// Zero values doesn't need a unit
|
|
49
|
+
if (value === 0 && this.unit.isLength()) {
|
|
50
|
+
output.add(strValue);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Float values doesn't need a leading zero
|
|
55
|
+
if (value > 0 && value < 1) {
|
|
56
|
+
strValue = (strValue).substr(1);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
output.add(strValue);
|
|
61
|
+
this.unit.genCSS(context, output);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// In an operation between two Dimensions,
|
|
65
|
+
// we default to the first Dimension's unit,
|
|
66
|
+
// so `1px + 2` will yield `3px`.
|
|
67
|
+
operate(context, op, other) {
|
|
68
|
+
/* jshint noempty:false */
|
|
69
|
+
let value = this._operate(context, op, this.value, other.value);
|
|
70
|
+
|
|
71
|
+
let unit = this.unit.clone();
|
|
72
|
+
|
|
73
|
+
if (op === '+' || op === '-') {
|
|
74
|
+
if (unit.numerator.length === 0 && unit.denominator.length === 0) {
|
|
75
|
+
unit = other.unit.clone();
|
|
76
|
+
if (this.unit.backupUnit) {
|
|
77
|
+
unit.backupUnit = this.unit.backupUnit;
|
|
78
|
+
}
|
|
79
|
+
} else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) {
|
|
80
|
+
// do nothing
|
|
81
|
+
} else {
|
|
82
|
+
other = other.convertTo(this.unit.usedUnits());
|
|
83
|
+
|
|
84
|
+
if (context.strictUnits && other.unit.toString() !== unit.toString()) {
|
|
85
|
+
throw new Error(`Incompatible units. Change the units or use the unit function. ` +
|
|
86
|
+
`Bad units: '${unit.toString()}' and '${other.unit.toString()}'.`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
value = this._operate(context, op, this.value, other.value);
|
|
90
|
+
}
|
|
91
|
+
} else if (op === '*') {
|
|
92
|
+
unit.numerator = unit.numerator.concat(other.unit.numerator).sort();
|
|
93
|
+
unit.denominator = unit.denominator.concat(other.unit.denominator).sort();
|
|
94
|
+
unit.cancel();
|
|
95
|
+
} else if (op === '/') {
|
|
96
|
+
unit.numerator = unit.numerator.concat(other.unit.denominator).sort();
|
|
97
|
+
unit.denominator = unit.denominator.concat(other.unit.numerator).sort();
|
|
98
|
+
unit.cancel();
|
|
99
|
+
}
|
|
100
|
+
return new Dimension(value, unit);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
compare(other) {
|
|
104
|
+
let a;
|
|
105
|
+
let b;
|
|
106
|
+
|
|
107
|
+
if (!(other instanceof Dimension)) {
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (this.unit.isEmpty() || other.unit.isEmpty()) {
|
|
112
|
+
a = this;
|
|
113
|
+
b = other;
|
|
114
|
+
} else {
|
|
115
|
+
a = this.unify();
|
|
116
|
+
b = other.unify();
|
|
117
|
+
if (a.unit.compare(b.unit) !== 0) {
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return Node.numericCompare(a.value, b.value);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
unify() {
|
|
126
|
+
return this.convertTo({ length: 'px', duration: 's', angle: 'rad' });
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
convertTo(conversions) {
|
|
130
|
+
let value = this.value;
|
|
131
|
+
const unit = this.unit.clone();
|
|
132
|
+
let i;
|
|
133
|
+
let groupName;
|
|
134
|
+
let group;
|
|
135
|
+
let targetUnit;
|
|
136
|
+
let derivedConversions = {};
|
|
137
|
+
let applyUnit;
|
|
138
|
+
|
|
139
|
+
if (typeof conversions === 'string') {
|
|
140
|
+
for (i in unitConversions) {
|
|
141
|
+
if (unitConversions[i].hasOwnProperty(conversions)) {
|
|
142
|
+
derivedConversions = {};
|
|
143
|
+
derivedConversions[i] = conversions;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
conversions = derivedConversions;
|
|
147
|
+
}
|
|
148
|
+
applyUnit = (atomicUnit, denominator) => {
|
|
149
|
+
/* jshint loopfunc:true */
|
|
150
|
+
if (group.hasOwnProperty(atomicUnit)) {
|
|
151
|
+
if (denominator) {
|
|
152
|
+
value = value / (group[atomicUnit] / group[targetUnit]);
|
|
153
|
+
} else {
|
|
154
|
+
value = value * (group[atomicUnit] / group[targetUnit]);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return targetUnit;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return atomicUnit;
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
for (groupName in conversions) {
|
|
164
|
+
if (conversions.hasOwnProperty(groupName)) {
|
|
165
|
+
targetUnit = conversions[groupName];
|
|
166
|
+
group = unitConversions[groupName];
|
|
167
|
+
|
|
168
|
+
unit.map(applyUnit);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
unit.cancel();
|
|
173
|
+
|
|
174
|
+
return new Dimension(value, unit);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
Dimension.prototype.type = 'Dimension';
|
|
179
|
+
export default Dimension;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import Node from './node';
|
|
2
|
+
import Paren from './paren';
|
|
3
|
+
import Combinator from './combinator';
|
|
4
|
+
|
|
5
|
+
class Element extends Node {
|
|
6
|
+
constructor(combinator, value, isVariable, index, currentFileInfo, visibilityInfo) {
|
|
7
|
+
super();
|
|
8
|
+
|
|
9
|
+
this.combinator = combinator instanceof Combinator ?
|
|
10
|
+
combinator : new Combinator(combinator);
|
|
11
|
+
|
|
12
|
+
if (typeof value === 'string') {
|
|
13
|
+
this.value = value.trim();
|
|
14
|
+
} else if (value) {
|
|
15
|
+
this.value = value;
|
|
16
|
+
} else {
|
|
17
|
+
this.value = '';
|
|
18
|
+
}
|
|
19
|
+
this.isVariable = isVariable;
|
|
20
|
+
this._index = index;
|
|
21
|
+
this._fileInfo = currentFileInfo;
|
|
22
|
+
this.copyVisibilityInfo(visibilityInfo);
|
|
23
|
+
this.setParent(this.combinator, this);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
accept(visitor) {
|
|
27
|
+
const value = this.value;
|
|
28
|
+
this.combinator = visitor.visit(this.combinator);
|
|
29
|
+
if (typeof value === 'object') {
|
|
30
|
+
this.value = visitor.visit(value);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
eval(context) {
|
|
35
|
+
return new Element(this.combinator,
|
|
36
|
+
this.value.eval ? this.value.eval(context) : this.value,
|
|
37
|
+
this.isVariable,
|
|
38
|
+
this.getIndex(),
|
|
39
|
+
this.fileInfo(), this.visibilityInfo());
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
clone() {
|
|
43
|
+
return new Element(this.combinator,
|
|
44
|
+
this.value,
|
|
45
|
+
this.isVariable,
|
|
46
|
+
this.getIndex(),
|
|
47
|
+
this.fileInfo(), this.visibilityInfo());
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
genCSS(context, output) {
|
|
51
|
+
output.add(this.toCSS(context), this.fileInfo(), this.getIndex());
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
toCSS(context = {}) {
|
|
55
|
+
let value = this.value;
|
|
56
|
+
const firstSelector = context.firstSelector;
|
|
57
|
+
if (value instanceof Paren) {
|
|
58
|
+
// selector in parens should not be affected by outer selector
|
|
59
|
+
// flags (breaks only interpolated selectors - see #1973)
|
|
60
|
+
context.firstSelector = true;
|
|
61
|
+
}
|
|
62
|
+
value = value.toCSS ? value.toCSS(context) : value;
|
|
63
|
+
context.firstSelector = firstSelector;
|
|
64
|
+
if (value === '' && this.combinator.value.charAt(0) === '&') {
|
|
65
|
+
return '';
|
|
66
|
+
} else {
|
|
67
|
+
return this.combinator.toCSS(context) + value;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
Element.prototype.type = 'Element';
|
|
73
|
+
export default Element;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import Node from './node';
|
|
2
|
+
import Paren from './paren';
|
|
3
|
+
import Comment from './comment';
|
|
4
|
+
import Dimension from './dimension';
|
|
5
|
+
import * as Constants from '../constants';
|
|
6
|
+
const MATH = Constants.Math;
|
|
7
|
+
|
|
8
|
+
class Expression extends Node {
|
|
9
|
+
constructor(value, noSpacing) {
|
|
10
|
+
super();
|
|
11
|
+
|
|
12
|
+
this.value = value;
|
|
13
|
+
this.noSpacing = noSpacing;
|
|
14
|
+
if (!value) {
|
|
15
|
+
throw new Error('Expression requires an array parameter');
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
accept(visitor) {
|
|
20
|
+
this.value = visitor.visitArray(this.value);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
eval(context) {
|
|
24
|
+
let returnValue;
|
|
25
|
+
const mathOn = context.isMathOn();
|
|
26
|
+
|
|
27
|
+
const inParenthesis = this.parens &&
|
|
28
|
+
(context.math !== MATH.STRICT_LEGACY || !this.parensInOp);
|
|
29
|
+
|
|
30
|
+
let doubleParen = false;
|
|
31
|
+
if (inParenthesis) {
|
|
32
|
+
context.inParenthesis();
|
|
33
|
+
}
|
|
34
|
+
if (this.value.length > 1) {
|
|
35
|
+
returnValue = new Expression(this.value.map(e => {
|
|
36
|
+
if (!e.eval) {
|
|
37
|
+
return e;
|
|
38
|
+
}
|
|
39
|
+
return e.eval(context);
|
|
40
|
+
}), this.noSpacing);
|
|
41
|
+
} else if (this.value.length === 1) {
|
|
42
|
+
if (this.value[0].parens && !this.value[0].parensInOp && !context.inCalc) {
|
|
43
|
+
doubleParen = true;
|
|
44
|
+
}
|
|
45
|
+
returnValue = this.value[0].eval(context);
|
|
46
|
+
} else {
|
|
47
|
+
returnValue = this;
|
|
48
|
+
}
|
|
49
|
+
if (inParenthesis) {
|
|
50
|
+
context.outOfParenthesis();
|
|
51
|
+
}
|
|
52
|
+
if (this.parens && this.parensInOp && !mathOn && !doubleParen
|
|
53
|
+
&& (!(returnValue instanceof Dimension))) {
|
|
54
|
+
returnValue = new Paren(returnValue);
|
|
55
|
+
}
|
|
56
|
+
return returnValue;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
genCSS(context, output) {
|
|
60
|
+
for (let i = 0; i < this.value.length; i++) {
|
|
61
|
+
this.value[i].genCSS(context, output);
|
|
62
|
+
if (!this.noSpacing && i + 1 < this.value.length) {
|
|
63
|
+
output.add(' ');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
throwAwayComments() {
|
|
69
|
+
this.value = this.value.filter(v => !(v instanceof Comment));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
Expression.prototype.type = 'Expression';
|
|
74
|
+
export default Expression;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import Node from './node';
|
|
2
|
+
import Selector from './selector';
|
|
3
|
+
|
|
4
|
+
class Extend extends Node {
|
|
5
|
+
constructor(selector, option, index, currentFileInfo, visibilityInfo) {
|
|
6
|
+
super();
|
|
7
|
+
|
|
8
|
+
this.selector = selector;
|
|
9
|
+
this.option = option;
|
|
10
|
+
this.object_id = Extend.next_id++;
|
|
11
|
+
this.parent_ids = [this.object_id];
|
|
12
|
+
this._index = index;
|
|
13
|
+
this._fileInfo = currentFileInfo;
|
|
14
|
+
this.copyVisibilityInfo(visibilityInfo);
|
|
15
|
+
this.allowRoot = true;
|
|
16
|
+
|
|
17
|
+
switch (option) {
|
|
18
|
+
case 'all':
|
|
19
|
+
this.allowBefore = true;
|
|
20
|
+
this.allowAfter = true;
|
|
21
|
+
break;
|
|
22
|
+
default:
|
|
23
|
+
this.allowBefore = false;
|
|
24
|
+
this.allowAfter = false;
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
this.setParent(this.selector, this);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
accept(visitor) {
|
|
31
|
+
this.selector = visitor.visit(this.selector);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
eval(context) {
|
|
35
|
+
return new Extend(this.selector.eval(context), this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo());
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
clone(context) {
|
|
39
|
+
return new Extend(this.selector, this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo());
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// it concatenates (joins) all selectors in selector array
|
|
43
|
+
findSelfSelectors(selectors) {
|
|
44
|
+
let selfElements = [];
|
|
45
|
+
let i;
|
|
46
|
+
let selectorElements;
|
|
47
|
+
|
|
48
|
+
for (i = 0; i < selectors.length; i++) {
|
|
49
|
+
selectorElements = selectors[i].elements;
|
|
50
|
+
// duplicate the logic in genCSS function inside the selector node.
|
|
51
|
+
// future TODO - move both logics into the selector joiner visitor
|
|
52
|
+
if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === '') {
|
|
53
|
+
selectorElements[0].combinator.value = ' ';
|
|
54
|
+
}
|
|
55
|
+
selfElements = selfElements.concat(selectors[i].elements);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
this.selfSelectors = [new Selector(selfElements)];
|
|
59
|
+
this.selfSelectors[0].copyVisibilityInfo(this.visibilityInfo());
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
Extend.next_id = 0;
|
|
64
|
+
|
|
65
|
+
Extend.prototype.type = 'Extend';
|
|
66
|
+
export default Extend;
|