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,215 @@
|
|
|
1
|
+
import Node from './node';
|
|
2
|
+
import Selector from './selector';
|
|
3
|
+
import MixinDefinition from './mixin-definition';
|
|
4
|
+
import defaultFunc from '../functions/default';
|
|
5
|
+
|
|
6
|
+
class MixinCall extends Node {
|
|
7
|
+
constructor(elements, args, index, currentFileInfo, important) {
|
|
8
|
+
super();
|
|
9
|
+
|
|
10
|
+
this.selector = new Selector(elements);
|
|
11
|
+
this.arguments = args || [];
|
|
12
|
+
this._index = index;
|
|
13
|
+
this._fileInfo = currentFileInfo;
|
|
14
|
+
this.important = important;
|
|
15
|
+
this.allowRoot = true;
|
|
16
|
+
this.setParent(this.selector, this);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
accept(visitor) {
|
|
20
|
+
if (this.selector) {
|
|
21
|
+
this.selector = visitor.visit(this.selector);
|
|
22
|
+
}
|
|
23
|
+
if (this.arguments.length) {
|
|
24
|
+
this.arguments = visitor.visitArray(this.arguments);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
eval(context) {
|
|
29
|
+
let mixins;
|
|
30
|
+
let mixin;
|
|
31
|
+
let mixinPath;
|
|
32
|
+
const args = [];
|
|
33
|
+
let arg;
|
|
34
|
+
let argValue;
|
|
35
|
+
const rules = [];
|
|
36
|
+
let match = false;
|
|
37
|
+
let i;
|
|
38
|
+
let m;
|
|
39
|
+
let f;
|
|
40
|
+
let isRecursive;
|
|
41
|
+
let isOneFound;
|
|
42
|
+
const candidates = [];
|
|
43
|
+
let candidate;
|
|
44
|
+
const conditionResult = [];
|
|
45
|
+
let defaultResult;
|
|
46
|
+
const defFalseEitherCase = -1;
|
|
47
|
+
const defNone = 0;
|
|
48
|
+
const defTrue = 1;
|
|
49
|
+
const defFalse = 2;
|
|
50
|
+
let count;
|
|
51
|
+
let originalRuleset;
|
|
52
|
+
let noArgumentsFilter;
|
|
53
|
+
|
|
54
|
+
this.selector = this.selector.eval(context);
|
|
55
|
+
|
|
56
|
+
function calcDefGroup(mixin, mixinPath) {
|
|
57
|
+
let f;
|
|
58
|
+
let p;
|
|
59
|
+
let namespace;
|
|
60
|
+
|
|
61
|
+
for (f = 0; f < 2; f++) {
|
|
62
|
+
conditionResult[f] = true;
|
|
63
|
+
defaultFunc.value(f);
|
|
64
|
+
for (p = 0; p < mixinPath.length && conditionResult[f]; p++) {
|
|
65
|
+
namespace = mixinPath[p];
|
|
66
|
+
if (namespace.matchCondition) {
|
|
67
|
+
conditionResult[f] = conditionResult[f] && namespace.matchCondition(null, context);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (mixin.matchCondition) {
|
|
71
|
+
conditionResult[f] = conditionResult[f] && mixin.matchCondition(args, context);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (conditionResult[0] || conditionResult[1]) {
|
|
75
|
+
if (conditionResult[0] != conditionResult[1]) {
|
|
76
|
+
return conditionResult[1] ?
|
|
77
|
+
defTrue : defFalse;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return defNone;
|
|
81
|
+
}
|
|
82
|
+
return defFalseEitherCase;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
for (i = 0; i < this.arguments.length; i++) {
|
|
86
|
+
arg = this.arguments[i];
|
|
87
|
+
argValue = arg.value.eval(context);
|
|
88
|
+
if (arg.expand && Array.isArray(argValue.value)) {
|
|
89
|
+
argValue = argValue.value;
|
|
90
|
+
for (m = 0; m < argValue.length; m++) {
|
|
91
|
+
args.push({value: argValue[m]});
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
args.push({name: arg.name, value: argValue});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
noArgumentsFilter = rule => rule.matchArgs(null, context);
|
|
99
|
+
|
|
100
|
+
for (i = 0; i < context.frames.length; i++) {
|
|
101
|
+
if ((mixins = context.frames[i].find(this.selector, null, noArgumentsFilter)).length > 0) {
|
|
102
|
+
isOneFound = true;
|
|
103
|
+
|
|
104
|
+
// To make `default()` function independent of definition order we have two "subpasses" here.
|
|
105
|
+
// At first we evaluate each guard *twice* (with `default() == true` and `default() == false`),
|
|
106
|
+
// and build candidate list with corresponding flags. Then, when we know all possible matches,
|
|
107
|
+
// we make a final decision.
|
|
108
|
+
|
|
109
|
+
for (m = 0; m < mixins.length; m++) {
|
|
110
|
+
mixin = mixins[m].rule;
|
|
111
|
+
mixinPath = mixins[m].path;
|
|
112
|
+
isRecursive = false;
|
|
113
|
+
for (f = 0; f < context.frames.length; f++) {
|
|
114
|
+
if ((!(mixin instanceof MixinDefinition)) && mixin === (context.frames[f].originalRuleset || context.frames[f])) {
|
|
115
|
+
isRecursive = true;
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (isRecursive) {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (mixin.matchArgs(args, context)) {
|
|
124
|
+
candidate = {mixin, group: calcDefGroup(mixin, mixinPath)};
|
|
125
|
+
|
|
126
|
+
if (candidate.group !== defFalseEitherCase) {
|
|
127
|
+
candidates.push(candidate);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
match = true;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
defaultFunc.reset();
|
|
135
|
+
|
|
136
|
+
count = [0, 0, 0];
|
|
137
|
+
for (m = 0; m < candidates.length; m++) {
|
|
138
|
+
count[candidates[m].group]++;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (count[defNone] > 0) {
|
|
142
|
+
defaultResult = defFalse;
|
|
143
|
+
} else {
|
|
144
|
+
defaultResult = defTrue;
|
|
145
|
+
if ((count[defTrue] + count[defFalse]) > 1) {
|
|
146
|
+
throw { type: 'Runtime',
|
|
147
|
+
message: `Ambiguous use of \`default()\` found when matching for \`${this.format(args)}\``,
|
|
148
|
+
index: this.getIndex(), filename: this.fileInfo().filename };
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
for (m = 0; m < candidates.length; m++) {
|
|
153
|
+
candidate = candidates[m].group;
|
|
154
|
+
if ((candidate === defNone) || (candidate === defaultResult)) {
|
|
155
|
+
try {
|
|
156
|
+
mixin = candidates[m].mixin;
|
|
157
|
+
if (!(mixin instanceof MixinDefinition)) {
|
|
158
|
+
originalRuleset = mixin.originalRuleset || mixin;
|
|
159
|
+
mixin = new MixinDefinition('', [], mixin.rules, null, false, null, originalRuleset.visibilityInfo());
|
|
160
|
+
mixin.originalRuleset = originalRuleset;
|
|
161
|
+
}
|
|
162
|
+
const newRules = mixin.evalCall(context, args, this.important).rules;
|
|
163
|
+
this._setVisibilityToReplacement(newRules);
|
|
164
|
+
Array.prototype.push.apply(rules, newRules);
|
|
165
|
+
} catch (e) {
|
|
166
|
+
throw { message: e.message, index: this.getIndex(), filename: this.fileInfo().filename, stack: e.stack };
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (match) {
|
|
172
|
+
return rules;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (isOneFound) {
|
|
177
|
+
throw { type: 'Runtime',
|
|
178
|
+
message: `No matching definition was found for \`${this.format(args)}\``,
|
|
179
|
+
index: this.getIndex(), filename: this.fileInfo().filename };
|
|
180
|
+
} else {
|
|
181
|
+
throw { type: 'Name',
|
|
182
|
+
message: `${this.selector.toCSS().trim()} is undefined`,
|
|
183
|
+
index: this.getIndex(), filename: this.fileInfo().filename };
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
_setVisibilityToReplacement(replacement) {
|
|
188
|
+
let i;
|
|
189
|
+
let rule;
|
|
190
|
+
if (this.blocksVisibility()) {
|
|
191
|
+
for (i = 0; i < replacement.length; i++) {
|
|
192
|
+
rule = replacement[i];
|
|
193
|
+
rule.addVisibilityBlock();
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
format(args) {
|
|
199
|
+
return `${this.selector.toCSS().trim()}(${args ? args.map(a => {
|
|
200
|
+
let argValue = '';
|
|
201
|
+
if (a.name) {
|
|
202
|
+
argValue += `${a.name}:`;
|
|
203
|
+
}
|
|
204
|
+
if (a.value.toCSS) {
|
|
205
|
+
argValue += a.value.toCSS();
|
|
206
|
+
} else {
|
|
207
|
+
argValue += '???';
|
|
208
|
+
}
|
|
209
|
+
return argValue;
|
|
210
|
+
}).join(', ') : ''})`;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
MixinCall.prototype.type = 'MixinCall';
|
|
215
|
+
export default MixinCall;
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import Selector from './selector';
|
|
2
|
+
import Element from './element';
|
|
3
|
+
import Ruleset from './ruleset';
|
|
4
|
+
import Declaration from './declaration';
|
|
5
|
+
import DetachedRuleset from './detached-ruleset';
|
|
6
|
+
import Expression from './expression';
|
|
7
|
+
import contexts from '../contexts';
|
|
8
|
+
import * as utils from '../utils';
|
|
9
|
+
|
|
10
|
+
class Definition extends Ruleset {
|
|
11
|
+
constructor(name, params, rules, condition, variadic, frames, visibilityInfo) {
|
|
12
|
+
super();
|
|
13
|
+
|
|
14
|
+
this.name = name || 'anonymous mixin';
|
|
15
|
+
this.selectors = [new Selector([new Element(null, name, false, this._index, this._fileInfo)])];
|
|
16
|
+
this.params = params;
|
|
17
|
+
this.condition = condition;
|
|
18
|
+
this.variadic = variadic;
|
|
19
|
+
this.arity = params.length;
|
|
20
|
+
this.rules = rules;
|
|
21
|
+
this._lookups = {};
|
|
22
|
+
const optionalParameters = [];
|
|
23
|
+
this.required = params.reduce((count, p) => {
|
|
24
|
+
if (!p.name || (p.name && !p.value)) {
|
|
25
|
+
return count + 1;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
optionalParameters.push(p.name);
|
|
29
|
+
return count;
|
|
30
|
+
}
|
|
31
|
+
}, 0);
|
|
32
|
+
this.optionalParameters = optionalParameters;
|
|
33
|
+
this.frames = frames;
|
|
34
|
+
this.copyVisibilityInfo(visibilityInfo);
|
|
35
|
+
this.allowRoot = true;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
accept(visitor) {
|
|
39
|
+
if (this.params && this.params.length) {
|
|
40
|
+
this.params = visitor.visitArray(this.params);
|
|
41
|
+
}
|
|
42
|
+
this.rules = visitor.visitArray(this.rules);
|
|
43
|
+
if (this.condition) {
|
|
44
|
+
this.condition = visitor.visit(this.condition);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
evalParams(context, mixinEnv, args, evaldArguments) {
|
|
49
|
+
/* jshint boss:true */
|
|
50
|
+
const frame = new Ruleset(null, null);
|
|
51
|
+
|
|
52
|
+
let varargs;
|
|
53
|
+
let arg;
|
|
54
|
+
const params = utils.copyArray(this.params);
|
|
55
|
+
let i;
|
|
56
|
+
let j;
|
|
57
|
+
let val;
|
|
58
|
+
let name;
|
|
59
|
+
let isNamedFound;
|
|
60
|
+
let argIndex;
|
|
61
|
+
let argsLength = 0;
|
|
62
|
+
|
|
63
|
+
if (mixinEnv.frames && mixinEnv.frames[0] && mixinEnv.frames[0].functionRegistry) {
|
|
64
|
+
frame.functionRegistry = mixinEnv.frames[0].functionRegistry.inherit();
|
|
65
|
+
}
|
|
66
|
+
mixinEnv = new contexts.Eval(mixinEnv, [frame].concat(mixinEnv.frames));
|
|
67
|
+
|
|
68
|
+
if (args) {
|
|
69
|
+
args = utils.copyArray(args);
|
|
70
|
+
argsLength = args.length;
|
|
71
|
+
|
|
72
|
+
for (i = 0; i < argsLength; i++) {
|
|
73
|
+
arg = args[i];
|
|
74
|
+
if (name = (arg && arg.name)) {
|
|
75
|
+
isNamedFound = false;
|
|
76
|
+
for (j = 0; j < params.length; j++) {
|
|
77
|
+
if (!evaldArguments[j] && name === params[j].name) {
|
|
78
|
+
evaldArguments[j] = arg.value.eval(context);
|
|
79
|
+
frame.prependRule(new Declaration(name, arg.value.eval(context)));
|
|
80
|
+
isNamedFound = true;
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (isNamedFound) {
|
|
85
|
+
args.splice(i, 1);
|
|
86
|
+
i--;
|
|
87
|
+
continue;
|
|
88
|
+
} else {
|
|
89
|
+
throw { type: 'Runtime', message: `Named argument for ${this.name} ${args[i].name} not found` };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
argIndex = 0;
|
|
95
|
+
for (i = 0; i < params.length; i++) {
|
|
96
|
+
if (evaldArguments[i]) { continue; }
|
|
97
|
+
|
|
98
|
+
arg = args && args[argIndex];
|
|
99
|
+
|
|
100
|
+
if (name = params[i].name) {
|
|
101
|
+
if (params[i].variadic) {
|
|
102
|
+
varargs = [];
|
|
103
|
+
for (j = argIndex; j < argsLength; j++) {
|
|
104
|
+
varargs.push(args[j].value.eval(context));
|
|
105
|
+
}
|
|
106
|
+
frame.prependRule(new Declaration(name, new Expression(varargs).eval(context)));
|
|
107
|
+
} else {
|
|
108
|
+
val = arg && arg.value;
|
|
109
|
+
if (val) {
|
|
110
|
+
// This was a mixin call, pass in a detached ruleset of it's eval'd rules
|
|
111
|
+
if (Array.isArray(val)) {
|
|
112
|
+
val = new DetachedRuleset(new Ruleset('', val));
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
val = val.eval(context);
|
|
116
|
+
}
|
|
117
|
+
} else if (params[i].value) {
|
|
118
|
+
val = params[i].value.eval(mixinEnv);
|
|
119
|
+
frame.resetCache();
|
|
120
|
+
} else {
|
|
121
|
+
throw { type: 'Runtime', message: `wrong number of arguments for ${this.name} (${argsLength} for ${this.arity})` };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
frame.prependRule(new Declaration(name, val));
|
|
125
|
+
evaldArguments[i] = val;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (params[i].variadic && args) {
|
|
130
|
+
for (j = argIndex; j < argsLength; j++) {
|
|
131
|
+
evaldArguments[j] = args[j].value.eval(context);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
argIndex++;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return frame;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
makeImportant() {
|
|
141
|
+
const rules = !this.rules ? this.rules : this.rules.map(r => {
|
|
142
|
+
if (r.makeImportant) {
|
|
143
|
+
return r.makeImportant(true);
|
|
144
|
+
} else {
|
|
145
|
+
return r;
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
const result = new Definition(this.name, this.params, rules, this.condition, this.variadic, this.frames);
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
eval(context) {
|
|
153
|
+
return new Definition(this.name, this.params, this.rules, this.condition, this.variadic, this.frames || utils.copyArray(context.frames));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
evalCall(context, args, important) {
|
|
157
|
+
const _arguments = [];
|
|
158
|
+
const mixinFrames = this.frames ? this.frames.concat(context.frames) : context.frames;
|
|
159
|
+
const frame = this.evalParams(context, new contexts.Eval(context, mixinFrames), args, _arguments);
|
|
160
|
+
let rules;
|
|
161
|
+
let ruleset;
|
|
162
|
+
|
|
163
|
+
frame.prependRule(new Declaration('@arguments', new Expression(_arguments).eval(context)));
|
|
164
|
+
|
|
165
|
+
rules = utils.copyArray(this.rules);
|
|
166
|
+
|
|
167
|
+
ruleset = new Ruleset(null, rules);
|
|
168
|
+
ruleset.originalRuleset = this;
|
|
169
|
+
ruleset = ruleset.eval(new contexts.Eval(context, [this, frame].concat(mixinFrames)));
|
|
170
|
+
if (important) {
|
|
171
|
+
ruleset = ruleset.makeImportant();
|
|
172
|
+
}
|
|
173
|
+
return ruleset;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
matchCondition(args, context) {
|
|
177
|
+
if (this.condition && !this.condition.eval(
|
|
178
|
+
new contexts.Eval(context,
|
|
179
|
+
[this.evalParams(context, /* the parameter variables */
|
|
180
|
+
new contexts.Eval(context, this.frames ? this.frames.concat(context.frames) : context.frames), args, [])]
|
|
181
|
+
.concat(this.frames || []) // the parent namespace/mixin frames
|
|
182
|
+
.concat(context.frames)))) { // the current environment frames
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
matchArgs(args, context) {
|
|
189
|
+
const allArgsCnt = (args && args.length) || 0;
|
|
190
|
+
let len;
|
|
191
|
+
const optionalParameters = this.optionalParameters;
|
|
192
|
+
const requiredArgsCnt = !args ? 0 : args.reduce((count, p) => {
|
|
193
|
+
if (optionalParameters.indexOf(p.name) < 0) {
|
|
194
|
+
return count + 1;
|
|
195
|
+
} else {
|
|
196
|
+
return count;
|
|
197
|
+
}
|
|
198
|
+
}, 0);
|
|
199
|
+
|
|
200
|
+
if (!this.variadic) {
|
|
201
|
+
if (requiredArgsCnt < this.required) {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
if (allArgsCnt > this.params.length) {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
} else {
|
|
208
|
+
if (requiredArgsCnt < (this.required - 1)) {
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// check patterns
|
|
214
|
+
len = Math.min(requiredArgsCnt, this.arity);
|
|
215
|
+
|
|
216
|
+
for (let i = 0; i < len; i++) {
|
|
217
|
+
if (!this.params[i].name && !this.params[i].variadic) {
|
|
218
|
+
if (args[i].value.eval(context).toCSS() != this.params[i].value.eval(context).toCSS()) {
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
Definition.prototype.type = 'MixinDefinition';
|
|
228
|
+
Definition.prototype.evalFirst = true;
|
|
229
|
+
export default Definition;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import Node from './node';
|
|
2
|
+
import Variable from './variable';
|
|
3
|
+
import Ruleset from './ruleset';
|
|
4
|
+
import Selector from './selector';
|
|
5
|
+
|
|
6
|
+
class NamespaceValue extends Node {
|
|
7
|
+
constructor(ruleCall, lookups, important, index, fileInfo) {
|
|
8
|
+
super();
|
|
9
|
+
|
|
10
|
+
this.value = ruleCall;
|
|
11
|
+
this.lookups = lookups;
|
|
12
|
+
this.important = important;
|
|
13
|
+
this._index = index;
|
|
14
|
+
this._fileInfo = fileInfo;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
eval(context) {
|
|
18
|
+
let i;
|
|
19
|
+
let j;
|
|
20
|
+
let name;
|
|
21
|
+
let rules = this.value.eval(context);
|
|
22
|
+
|
|
23
|
+
for (i = 0; i < this.lookups.length; i++) {
|
|
24
|
+
name = this.lookups[i];
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Eval'd DRs return rulesets.
|
|
28
|
+
* Eval'd mixins return rules, so let's make a ruleset if we need it.
|
|
29
|
+
* We need to do this because of late parsing of values
|
|
30
|
+
*/
|
|
31
|
+
if (Array.isArray(rules)) {
|
|
32
|
+
rules = new Ruleset([new Selector()], rules);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (name === '') {
|
|
36
|
+
rules = rules.lastDeclaration();
|
|
37
|
+
}
|
|
38
|
+
else if (name.charAt(0) === '@') {
|
|
39
|
+
if (name.charAt(1) === '@') {
|
|
40
|
+
name = `@${new Variable(name.substr(1)).eval(context).value}`;
|
|
41
|
+
}
|
|
42
|
+
if (rules.variables) {
|
|
43
|
+
rules = rules.variable(name);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!rules) {
|
|
47
|
+
throw { type: 'Name',
|
|
48
|
+
message: `variable ${name} not found`,
|
|
49
|
+
filename: this.fileInfo().filename,
|
|
50
|
+
index: this.getIndex() };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
if (name.substring(0, 2) === '$@') {
|
|
55
|
+
name = `$${new Variable(name.substr(1)).eval(context).value}`;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
name = name.charAt(0) === '$' ? name : `$${name}`;
|
|
59
|
+
}
|
|
60
|
+
if (rules.properties) {
|
|
61
|
+
rules = rules.property(name);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!rules) {
|
|
65
|
+
throw { type: 'Name',
|
|
66
|
+
message: `property "${name.substr(1)}" not found`,
|
|
67
|
+
filename: this.fileInfo().filename,
|
|
68
|
+
index: this.getIndex() };
|
|
69
|
+
}
|
|
70
|
+
// Properties are an array of values, since a ruleset can have multiple props.
|
|
71
|
+
// We pick the last one (the "cascaded" value)
|
|
72
|
+
rules = rules[rules.length - 1];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (rules.value) {
|
|
76
|
+
rules = rules.eval(context).value;
|
|
77
|
+
}
|
|
78
|
+
if (rules.ruleset) {
|
|
79
|
+
rules = rules.ruleset.eval(context);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return rules;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
NamespaceValue.prototype.type = 'NamespaceValue';
|
|
87
|
+
export default NamespaceValue;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import Node from './node';
|
|
2
|
+
import Operation from './operation';
|
|
3
|
+
import Dimension from './dimension';
|
|
4
|
+
|
|
5
|
+
class Negative extends Node {
|
|
6
|
+
constructor(node) {
|
|
7
|
+
super();
|
|
8
|
+
|
|
9
|
+
this.value = node;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
genCSS(context, output) {
|
|
13
|
+
output.add('-');
|
|
14
|
+
this.value.genCSS(context, output);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
eval(context) {
|
|
18
|
+
if (context.isMathOn()) {
|
|
19
|
+
return (new Operation('*', [new Dimension(-1), this.value])).eval(context);
|
|
20
|
+
}
|
|
21
|
+
return new Negative(this.value.eval(context));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
Negative.prototype.type = 'Negative';
|
|
26
|
+
export default Negative;
|