less-openui5 0.11.1 → 0.11.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/LICENSE.txt +197 -204
- package/lib/Compiler.js +185 -0
- package/lib/index.js +18 -219
- package/lib/plugin/css-variables-collector.js +56 -41
- package/lib/themingParameters/dataUri.js +33 -0
- package/package.json +13 -13
- package/CHANGELOG.md +0 -233
package/lib/index.js
CHANGED
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
const path = require("path");
|
|
4
|
-
const
|
|
5
|
-
|
|
4
|
+
const css = require("@adobe/css-tools");
|
|
5
|
+
|
|
6
6
|
|
|
7
|
-
const createParser = require("./less/parser");
|
|
8
7
|
const diff = require("./diff");
|
|
9
8
|
const scope = require("./scope");
|
|
10
9
|
|
|
11
10
|
const fileUtilsFactory = require("./fileUtils");
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
const UrlCollector = require("./plugin/url-collector");
|
|
12
|
+
const Compiler = require("./Compiler");
|
|
13
|
+
|
|
14
|
+
const themingParametersDataUri = require("./themingParameters/dataUri");
|
|
17
15
|
|
|
18
16
|
// Workaround for a performance issue in the "css" parser module when used in combination
|
|
19
17
|
// with the "colors" module that enhances the String prototype.
|
|
@@ -104,7 +102,7 @@ Builder.prototype.cacheTheme = function(result) {
|
|
|
104
102
|
};
|
|
105
103
|
|
|
106
104
|
/**
|
|
107
|
-
*
|
|
105
|
+
* Runs a theme build
|
|
108
106
|
* @param {object} options
|
|
109
107
|
* @param {object} options.compiler compiler object as passed to less
|
|
110
108
|
* @param {boolean} options.cssVariables whether or not to enable css variables output
|
|
@@ -115,10 +113,6 @@ Builder.prototype.cacheTheme = function(result) {
|
|
|
115
113
|
Builder.prototype.build = function(options) {
|
|
116
114
|
const that = this;
|
|
117
115
|
|
|
118
|
-
// Stores mapping between "virtual" paths (used within LESS) and real filesystem paths.
|
|
119
|
-
// Only relevant when using the "rootPaths" option.
|
|
120
|
-
const mFileMappings = {};
|
|
121
|
-
|
|
122
116
|
// Assign default options
|
|
123
117
|
options = Object.assign({
|
|
124
118
|
lessInput: null,
|
|
@@ -143,211 +137,14 @@ Builder.prototype.build = function(options) {
|
|
|
143
137
|
options.parser.relativeUrls = true;
|
|
144
138
|
}
|
|
145
139
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
pathname = path.posix.normalize(file);
|
|
152
|
-
} else {
|
|
153
|
-
pathname = path.posix.join(currentFileInfo.currentDirectory, file);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
that.fileUtils.readFile(pathname, options.rootPaths).then(function(result) {
|
|
157
|
-
if (!result) {
|
|
158
|
-
// eslint-disable-next-line no-console
|
|
159
|
-
console.log("File not found: " + pathname);
|
|
160
|
-
callback({type: "File", message: "Could not find file at path '" + pathname + "'"});
|
|
161
|
-
} else {
|
|
162
|
-
try {
|
|
163
|
-
// Save import mapping to calculate full import paths later on
|
|
164
|
-
mFileMappings[currentFileInfo.rootFilename] = mFileMappings[currentFileInfo.rootFilename] || {};
|
|
165
|
-
mFileMappings[currentFileInfo.rootFilename][pathname] = result.path;
|
|
166
|
-
|
|
167
|
-
handleDataAndCallCallback(pathname, result.content);
|
|
168
|
-
} catch (e) {
|
|
169
|
-
// eslint-disable-next-line no-console
|
|
170
|
-
console.log(e);
|
|
171
|
-
callback(e);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}, function(err) {
|
|
175
|
-
// eslint-disable-next-line no-console
|
|
176
|
-
console.log(err);
|
|
177
|
-
callback(err);
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
function compile(config) {
|
|
182
|
-
const parserOptions = clone(options.parser);
|
|
183
|
-
let rootpath;
|
|
184
|
-
|
|
185
|
-
if (config.path) {
|
|
186
|
-
// Keep rootpath for later usage in the ImportCollectorPlugin
|
|
187
|
-
rootpath = config.path;
|
|
188
|
-
parserOptions.filename = config.localPath;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// inject the library name as prefix (e.g. "sap.m" as "_sap_m")
|
|
192
|
-
if (options.library && typeof options.library.name === "string") {
|
|
193
|
-
const libName = config.libName = options.library.name;
|
|
194
|
-
config.prefix = "_" + libName.replace(/\./g, "_") + "_";
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// Keep filename for later usage (see ImportCollectorPlugin) as less modifies the parserOptions.filename
|
|
198
|
-
const filename = parserOptions.filename;
|
|
199
|
-
|
|
200
|
-
// Only use custom file handler when "rootPaths" or custom "fs" are used
|
|
201
|
-
let fnFileHandler;
|
|
202
|
-
if ((options.rootPaths && options.rootPaths.length > 0) || that.customFs) {
|
|
203
|
-
fnFileHandler = fileHandler;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
const parser = createParser(parserOptions, fnFileHandler);
|
|
207
|
-
|
|
208
|
-
return new Promise(function(resolve, reject) {
|
|
209
|
-
parser.parse(config.content, function(err, tree) {
|
|
210
|
-
if (err) {
|
|
211
|
-
reject(err);
|
|
212
|
-
} else {
|
|
213
|
-
resolve(tree);
|
|
214
|
-
}
|
|
215
|
-
});
|
|
216
|
-
}).then(async function(tree) {
|
|
217
|
-
const result = {};
|
|
218
|
-
|
|
219
|
-
result.tree = tree;
|
|
220
|
-
|
|
221
|
-
// plugins to collect imported files and variable values
|
|
222
|
-
const oImportCollector = new ImportCollectorPlugin({
|
|
223
|
-
importMappings: mFileMappings[filename]
|
|
224
|
-
});
|
|
225
|
-
const oVariableCollector = new VariableCollectorPlugin(options.compiler);
|
|
226
|
-
const oUrlCollector = new UrlCollector();
|
|
227
|
-
|
|
228
|
-
// render to css
|
|
229
|
-
result.css = tree.toCSS(Object.assign({}, options.compiler, {
|
|
230
|
-
plugins: [oImportCollector, oVariableCollector, oUrlCollector]
|
|
231
|
-
}));
|
|
232
|
-
|
|
233
|
-
// retrieve imported files
|
|
234
|
-
result.imports = oImportCollector.getImports();
|
|
235
|
-
|
|
236
|
-
// retrieve reduced set of variables
|
|
237
|
-
result.variables = oVariableCollector.getVariables(Object.keys(mFileMappings[filename] || {}));
|
|
238
|
-
|
|
239
|
-
// retrieve all variables
|
|
240
|
-
result.allVariables = oVariableCollector.getAllVariables();
|
|
241
|
-
|
|
242
|
-
// also compile rtl-version if requested
|
|
243
|
-
let oRTL;
|
|
244
|
-
if (options.rtl) {
|
|
245
|
-
const RTLPlugin = require("./plugin/rtl");
|
|
246
|
-
oRTL = new RTLPlugin();
|
|
247
|
-
|
|
248
|
-
const urls = oUrlCollector.getUrls();
|
|
249
|
-
|
|
250
|
-
const existingImgRtlUrls = (await Promise.all(
|
|
251
|
-
urls.map(async ({currentDirectory, relativeUrl}) => {
|
|
252
|
-
const relativeImgRtlUrl = RTLPlugin.getRtlImgUrl(relativeUrl);
|
|
253
|
-
if (relativeImgRtlUrl) {
|
|
254
|
-
const resolvedImgRtlUrl = path.posix.join(currentDirectory, relativeImgRtlUrl);
|
|
255
|
-
if (await that.fileUtils.findFile(resolvedImgRtlUrl, options.rootPaths)) {
|
|
256
|
-
return resolvedImgRtlUrl;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
})
|
|
260
|
-
)).filter(Boolean);
|
|
261
|
-
|
|
262
|
-
oRTL.setExistingImgRtlPaths(existingImgRtlUrls);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
if (oRTL) {
|
|
266
|
-
result.cssRtl = tree.toCSS(Object.assign({}, options.compiler, {
|
|
267
|
-
plugins: [oRTL]
|
|
268
|
-
}));
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
if (rootpath) {
|
|
272
|
-
result.imports.unshift(rootpath);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
// also compile css-variables version if requested
|
|
276
|
-
if (options.cssVariables) {
|
|
277
|
-
return new Promise(function(resolve, reject) {
|
|
278
|
-
// parse the content again to have a clean tree
|
|
279
|
-
parser.parse(config.content, function(err, tree) {
|
|
280
|
-
if (err) {
|
|
281
|
-
reject(err);
|
|
282
|
-
} else {
|
|
283
|
-
resolve(tree);
|
|
284
|
-
}
|
|
285
|
-
});
|
|
286
|
-
}).then(function(tree) {
|
|
287
|
-
// generate the skeleton-css and the less-variables
|
|
288
|
-
const CSSVariablesCollectorPlugin = require("./plugin/css-variables-collector");
|
|
289
|
-
const oCSSVariablesCollector = new CSSVariablesCollectorPlugin(config);
|
|
290
|
-
result.cssSkeleton = tree.toCSS(Object.assign({}, options.compiler, {
|
|
291
|
-
plugins: [oCSSVariablesCollector]
|
|
292
|
-
}));
|
|
293
|
-
result.cssVariablesSource = oCSSVariablesCollector.toLessVariables();
|
|
294
|
-
if (oRTL) {
|
|
295
|
-
const oCSSVariablesCollectorRTL = new CSSVariablesCollectorPlugin(config);
|
|
296
|
-
result.cssSkeletonRtl = tree.toCSS(Object.assign({}, options.compiler, {
|
|
297
|
-
plugins: [oCSSVariablesCollectorRTL, oRTL]
|
|
298
|
-
}));
|
|
299
|
-
}
|
|
300
|
-
return tree;
|
|
301
|
-
}).then(function(tree) {
|
|
302
|
-
// generate the css-variables content out of the less-variables
|
|
303
|
-
return new Promise(function(resolve, reject) {
|
|
304
|
-
parser.parse(result.cssVariablesSource, function(err, tree) {
|
|
305
|
-
if (err) {
|
|
306
|
-
reject(err);
|
|
307
|
-
} else {
|
|
308
|
-
const CSSVariablesPointerPlugin = require("./plugin/css-variables-pointer");
|
|
309
|
-
result.cssVariables = tree.toCSS(Object.assign({}, options.compiler, {
|
|
310
|
-
plugins: [new CSSVariablesPointerPlugin()]
|
|
311
|
-
}));
|
|
312
|
-
resolve(result);
|
|
313
|
-
}
|
|
314
|
-
});
|
|
315
|
-
});
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
return result;
|
|
320
|
-
});
|
|
321
|
-
}
|
|
140
|
+
const compiler = new Compiler({
|
|
141
|
+
options,
|
|
142
|
+
fileUtils: this.fileUtils,
|
|
143
|
+
customFs: this.customFs
|
|
144
|
+
});
|
|
322
145
|
|
|
323
146
|
function addInlineParameters(result) {
|
|
324
|
-
return
|
|
325
|
-
if (typeof options.library === "object" && typeof options.library.name === "string") {
|
|
326
|
-
const parameters = JSON.stringify(result.variables);
|
|
327
|
-
|
|
328
|
-
// properly escape the parameters to be part of a data-uri
|
|
329
|
-
// + escaping single quote (') as it is used to surround the data-uri: url('...')
|
|
330
|
-
const escapedParameters = encodeURIComponent(parameters).replace(/'/g, function(char) {
|
|
331
|
-
return escape(char);
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
// embed parameter variables as plain-text string into css
|
|
335
|
-
const parameterStyleRule = "\n/* Inline theming parameters */\n#sap-ui-theme-" +
|
|
336
|
-
options.library.name.replace(/\./g, "\\.") +
|
|
337
|
-
"{background-image:url('data:text/plain;utf-8," + escapedParameters + "')}\n";
|
|
338
|
-
|
|
339
|
-
// embed parameter variables as plain-text string into css
|
|
340
|
-
result.css += parameterStyleRule;
|
|
341
|
-
if (options.rtl) {
|
|
342
|
-
result.cssRtl += parameterStyleRule;
|
|
343
|
-
}
|
|
344
|
-
if (options.cssVariables) {
|
|
345
|
-
// for the css variables build we just add it to the variables
|
|
346
|
-
result.cssVariables += parameterStyleRule;
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
resolve(result);
|
|
350
|
-
});
|
|
147
|
+
return themingParametersDataUri.addInlineParameters({result, options});
|
|
351
148
|
}
|
|
352
149
|
|
|
353
150
|
function getScopeVariables(options) {
|
|
@@ -380,13 +177,13 @@ Builder.prototype.build = function(options) {
|
|
|
380
177
|
if (!config) {
|
|
381
178
|
throw new Error("Could not find embeddedCompareFile at path '" + scopeOptions.embeddedCompareFilePath + "'");
|
|
382
179
|
}
|
|
383
|
-
return compile(config);
|
|
180
|
+
return compiler.compile(config);
|
|
384
181
|
}),
|
|
385
182
|
that.fileUtils.readFile(scopeOptions.embeddedFilePath, options.rootPaths).then(function(config) {
|
|
386
183
|
if (!config) {
|
|
387
184
|
throw new Error("Could not find embeddedFile at path '" + scopeOptions.embeddedFilePath + "'");
|
|
388
185
|
}
|
|
389
|
-
return compile(config);
|
|
186
|
+
return compiler.compile(config);
|
|
390
187
|
})
|
|
391
188
|
]).then(function(results) {
|
|
392
189
|
return {
|
|
@@ -528,7 +325,9 @@ Builder.prototype.build = function(options) {
|
|
|
528
325
|
}
|
|
529
326
|
|
|
530
327
|
// No css diffing and scoping
|
|
531
|
-
return that.fileUtils.readFile(options.lessInputPath, options.rootPaths).then(
|
|
328
|
+
return that.fileUtils.readFile(options.lessInputPath, options.rootPaths).then((config) => {
|
|
329
|
+
return compiler.compile(config);
|
|
330
|
+
});
|
|
532
331
|
});
|
|
533
332
|
}
|
|
534
333
|
|
|
@@ -541,7 +340,7 @@ Builder.prototype.build = function(options) {
|
|
|
541
340
|
}
|
|
542
341
|
|
|
543
342
|
if (options.lessInput) {
|
|
544
|
-
return compile({
|
|
343
|
+
return compiler.compile({
|
|
545
344
|
content: options.lessInput
|
|
546
345
|
}).then(addInlineParameters).then(that.cacheTheme.bind(that));
|
|
547
346
|
} else {
|
|
@@ -11,12 +11,13 @@ const CSSVariablesCollectorPlugin = module.exports = function(config) {
|
|
|
11
11
|
this.ruleStack = [];
|
|
12
12
|
this.mixinStack = [];
|
|
13
13
|
this.parenStack = [];
|
|
14
|
-
this.importStack = [];
|
|
15
14
|
};
|
|
16
15
|
|
|
17
16
|
CSSVariablesCollectorPlugin.prototype = {
|
|
18
17
|
|
|
18
|
+
// needed to keep the less variable references intact to use this info for the CSS variables references
|
|
19
19
|
isPreEvalVisitor: true,
|
|
20
|
+
|
|
20
21
|
isReplacing: true,
|
|
21
22
|
|
|
22
23
|
_isInMixinOrParen() {
|
|
@@ -27,33 +28,47 @@ CSSVariablesCollectorPlugin.prototype = {
|
|
|
27
28
|
return this.ruleStack.length > 0 && !this.ruleStack[this.ruleStack.length - 1].variable;
|
|
28
29
|
},
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
_isVarInLibrary({filename} = {}) {
|
|
32
|
+
// for libraries we check that the file is within the libraries theme path
|
|
33
|
+
// in all other cases with no filename (indicates calculated variables)
|
|
34
|
+
// or in case of variables in standalone less files we just include them!
|
|
35
|
+
const regex = new RegExp(`(^|/)${this.config.libPath}/themes/`);
|
|
36
|
+
const include = !filename ||
|
|
37
|
+
(this.config.libPath ? regex.test(filename) : true);
|
|
38
|
+
return include;
|
|
34
39
|
},
|
|
35
40
|
|
|
36
41
|
_isRelevant() {
|
|
37
42
|
return !this._isInMixinOrParen() && this._isVarInRule();
|
|
38
43
|
},
|
|
39
44
|
|
|
40
|
-
toLessVariables() {
|
|
45
|
+
toLessVariables(varsOverride) {
|
|
46
|
+
const vars = {};
|
|
47
|
+
Object.keys(this.vars).forEach((variableName) => {
|
|
48
|
+
const override = this.vars[variableName].updateAfterEval && varsOverride[variableName] !== undefined;
|
|
49
|
+
vars[variableName] = {
|
|
50
|
+
css: override ? varsOverride[variableName] : this.vars[variableName].css,
|
|
51
|
+
export: this.vars[variableName].export
|
|
52
|
+
};
|
|
53
|
+
});
|
|
41
54
|
let lessVariables = "";
|
|
42
|
-
Object.keys(
|
|
43
|
-
|
|
55
|
+
Object.keys(vars).forEach((variableName) => {
|
|
56
|
+
const variableValue = vars[variableName].css;
|
|
57
|
+
lessVariables += `@${variableName}: ${variableValue};\n`;
|
|
44
58
|
});
|
|
45
|
-
Object.keys(this.calcVars).forEach((
|
|
46
|
-
|
|
59
|
+
Object.keys(this.calcVars).forEach((variableName) => {
|
|
60
|
+
const variableValue = this.calcVars[variableName].css;
|
|
61
|
+
lessVariables += `@${variableName}: ${variableValue};\n`;
|
|
47
62
|
});
|
|
48
63
|
lessVariables += "\n:root {\n";
|
|
49
|
-
Object.keys(
|
|
50
|
-
if (
|
|
51
|
-
lessVariables +=
|
|
64
|
+
Object.keys(vars).forEach((variableName) => {
|
|
65
|
+
if (vars[variableName].export) {
|
|
66
|
+
lessVariables += `--${variableName}: @${variableName};\n`;
|
|
52
67
|
}
|
|
53
68
|
});
|
|
54
|
-
Object.keys(this.calcVars).forEach((
|
|
55
|
-
if (this.calcVars[
|
|
56
|
-
lessVariables +=
|
|
69
|
+
Object.keys(this.calcVars).forEach((variableName) => {
|
|
70
|
+
if (this.calcVars[variableName].export) {
|
|
71
|
+
lessVariables += `--${variableName}: @${variableName};\n`;
|
|
57
72
|
}
|
|
58
73
|
});
|
|
59
74
|
lessVariables += "}\n";
|
|
@@ -89,15 +104,17 @@ CSSVariablesCollectorPlugin.prototype = {
|
|
|
89
104
|
|
|
90
105
|
visitOperation(node, visitArgs) {
|
|
91
106
|
if (this._isRelevant()) {
|
|
107
|
+
// console.log("visitOperation", this.ruleStack[this.ruleStack.length - 1], this._getCSS(node));
|
|
92
108
|
return new less.tree.Call("calc", [new less.tree.Expression([node.operands[0], new less.tree.Anonymous(node.op), node.operands[1]])]);
|
|
93
109
|
}
|
|
94
110
|
return node;
|
|
95
111
|
},
|
|
96
112
|
|
|
97
113
|
visitCall(node, visitArgs) {
|
|
98
|
-
// if variables are used inside rules, generate a new
|
|
114
|
+
// if variables are used inside rules, generate a new calculated variable for it!
|
|
99
115
|
const isRelevantFunction = typeof less.tree.functions[node.name] === "function" && ["rgba"].indexOf(node.name) === -1;
|
|
100
116
|
if (this._isRelevant() && isRelevantFunction) {
|
|
117
|
+
// console.log("visitCall", this.ruleStack[this.ruleStack.length - 1], this._getCSS(node));
|
|
101
118
|
const css = this._getCSS(node);
|
|
102
119
|
let newName = this.config.prefix + "function_" + node.name + Object.keys(this.vars).length;
|
|
103
120
|
// check for duplicate value in vars already
|
|
@@ -109,7 +126,7 @@ CSSVariablesCollectorPlugin.prototype = {
|
|
|
109
126
|
}
|
|
110
127
|
this.calcVars[newName] = {
|
|
111
128
|
css: css,
|
|
112
|
-
export:
|
|
129
|
+
export: this._isVarInLibrary()
|
|
113
130
|
};
|
|
114
131
|
return new less.tree.Call("var", [new less.tree.Anonymous("--" + newName, node.index, node.currentFileInfo, node.mapLines)]);
|
|
115
132
|
}
|
|
@@ -119,6 +136,7 @@ CSSVariablesCollectorPlugin.prototype = {
|
|
|
119
136
|
visitNegative(node, visitArgs) {
|
|
120
137
|
// convert negative into calc function
|
|
121
138
|
if (this._isRelevant()) {
|
|
139
|
+
// console.log("visitNegative", this.ruleStack[this.ruleStack.length - 1], this._getCSS(node));
|
|
122
140
|
return new less.tree.Call("calc", [new less.tree.Expression([new less.tree.Anonymous("-1"), new less.tree.Anonymous("*"), node.value])]);
|
|
123
141
|
}
|
|
124
142
|
return node;
|
|
@@ -133,6 +151,19 @@ CSSVariablesCollectorPlugin.prototype = {
|
|
|
133
151
|
},
|
|
134
152
|
|
|
135
153
|
visitRule(node, visitArgs) {
|
|
154
|
+
// check rule for being a variable declaration
|
|
155
|
+
const isVarDeclaration = typeof node.name === "string" && node.name.startsWith("@");
|
|
156
|
+
if (!this._isInMixinOrParen() && isVarDeclaration) {
|
|
157
|
+
// add the variable declaration to the list of vars
|
|
158
|
+
const varName = node.name.substr(1);
|
|
159
|
+
const isVarInLib = this._isVarInLibrary({
|
|
160
|
+
filename: node.currentFileInfo.filename
|
|
161
|
+
});
|
|
162
|
+
this.vars[varName] = {
|
|
163
|
+
css: this._getCSS(node.value),
|
|
164
|
+
export: isVarInLib
|
|
165
|
+
};
|
|
166
|
+
}
|
|
136
167
|
// store the rule context for the call variable extraction
|
|
137
168
|
this.ruleStack.push(node);
|
|
138
169
|
return node;
|
|
@@ -168,29 +199,13 @@ CSSVariablesCollectorPlugin.prototype = {
|
|
|
168
199
|
return node;
|
|
169
200
|
},
|
|
170
201
|
|
|
171
|
-
|
|
172
|
-
//
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
// remove import context
|
|
179
|
-
this.importStack.pop();
|
|
180
|
-
return node;
|
|
181
|
-
},
|
|
182
|
-
|
|
183
|
-
visitRuleset(node, visitArgs) {
|
|
184
|
-
node.rules.forEach((value) => {
|
|
185
|
-
const isVarDeclaration = value instanceof less.tree.Rule && typeof value.name === "string" && value.name.startsWith("@");
|
|
186
|
-
if (!this._isInMixinOrParen() && isVarDeclaration) {
|
|
187
|
-
// add the variable declaration to the list of vars
|
|
188
|
-
this.vars[value.name.substr(1)] = {
|
|
189
|
-
css: this._getCSS(value.value),
|
|
190
|
-
export: !this._isInGlobalOrBaseImport()
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
});
|
|
202
|
+
visitUrl(node, visitArgs) {
|
|
203
|
+
// we mark the less variables which should be updated after eval
|
|
204
|
+
// => strangewise less variables with "none" values are also urls
|
|
205
|
+
// after the less variables have been evaluated
|
|
206
|
+
if (this.ruleStack.length > 0 && this.ruleStack[0].variable) {
|
|
207
|
+
this.vars[this.ruleStack[0].name.substr(1)].updateAfterEval = true;
|
|
208
|
+
}
|
|
194
209
|
return node;
|
|
195
210
|
}
|
|
196
211
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
addInlineParameters: function({result, options}) {
|
|
3
|
+
// Inline parameters can only be added when the library name is known
|
|
4
|
+
if (typeof options.library !== "object" || typeof options.library.name !== "string") {
|
|
5
|
+
return result;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const parameters = JSON.stringify(result.variables);
|
|
9
|
+
|
|
10
|
+
// properly escape the parameters to be part of a data-uri
|
|
11
|
+
// + escaping single quote (') as it is used to surround the data-uri: url('...')
|
|
12
|
+
const escapedParameters = encodeURIComponent(parameters).replace(/'/g, function(char) {
|
|
13
|
+
return escape(char);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
// embed parameter variables as plain-text string into css
|
|
17
|
+
const parameterStyleRule = "\n/* Inline theming parameters */\n#sap-ui-theme-" +
|
|
18
|
+
options.library.name.replace(/\./g, "\\.") +
|
|
19
|
+
"{background-image:url('data:text/plain;utf-8," + escapedParameters + "')}\n";
|
|
20
|
+
|
|
21
|
+
// embed parameter variables as plain-text string into css
|
|
22
|
+
result.css += parameterStyleRule;
|
|
23
|
+
if (options.rtl) {
|
|
24
|
+
result.cssRtl += parameterStyleRule;
|
|
25
|
+
}
|
|
26
|
+
if (options.cssVariables) {
|
|
27
|
+
// for the css variables build we just add it to the variables
|
|
28
|
+
result.cssVariables += parameterStyleRule;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "less-openui5",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.3",
|
|
4
4
|
"description": "Build OpenUI5 themes with Less.js",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "SAP SE",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
},
|
|
24
24
|
"scripts": {
|
|
25
25
|
"lint": "eslint ./",
|
|
26
|
-
"unit": "mocha test/*.js",
|
|
27
|
-
"unit-debug": "mocha --inspect --inspect-brk test/*.js",
|
|
26
|
+
"unit": "mocha test/*.js test/lib/**",
|
|
27
|
+
"unit-debug": "mocha --inspect --inspect-brk test/*.js test/lib/**",
|
|
28
28
|
"coverage": "nyc npm run unit",
|
|
29
29
|
"test": "npm run lint && npm run coverage && npm run depcheck",
|
|
30
30
|
"preversion": "npm test",
|
|
@@ -52,10 +52,10 @@
|
|
|
52
52
|
"lib/thirdparty/**"
|
|
53
53
|
],
|
|
54
54
|
"check-coverage": true,
|
|
55
|
-
"statements":
|
|
55
|
+
"statements": 95,
|
|
56
56
|
"branches": 85,
|
|
57
|
-
"functions":
|
|
58
|
-
"lines":
|
|
57
|
+
"functions": 100,
|
|
58
|
+
"lines": 95,
|
|
59
59
|
"watermarks": {
|
|
60
60
|
"statements": [
|
|
61
61
|
70,
|
|
@@ -82,17 +82,17 @@
|
|
|
82
82
|
"url": "git@github.com:SAP/less-openui5.git"
|
|
83
83
|
},
|
|
84
84
|
"dependencies": {
|
|
85
|
-
"
|
|
86
|
-
"
|
|
85
|
+
"@adobe/css-tools": "^4.0.1",
|
|
86
|
+
"clone": "^2.1.2",
|
|
87
87
|
"mime": "^1.6.0"
|
|
88
88
|
},
|
|
89
89
|
"devDependencies": {
|
|
90
|
-
"depcheck": "^1.4.
|
|
91
|
-
"eslint": "^7.
|
|
90
|
+
"depcheck": "^1.4.3",
|
|
91
|
+
"eslint": "^7.32.0",
|
|
92
92
|
"eslint-config-google": "^0.14.0",
|
|
93
|
-
"graceful-fs": "^4.2.
|
|
94
|
-
"mocha": "^8.
|
|
93
|
+
"graceful-fs": "^4.2.10",
|
|
94
|
+
"mocha": "^8.4.0",
|
|
95
95
|
"nyc": "^15.1.0",
|
|
96
|
-
"sinon": "^
|
|
96
|
+
"sinon": "^11.1.2"
|
|
97
97
|
}
|
|
98
98
|
}
|