less-openui5
Advanced tools
Comparing version 0.11.2 to 0.11.3
242
lib/index.js
"use strict"; | ||
const path = require("path"); | ||
const clone = require("clone"); | ||
const css = require("css"); | ||
const css = require("@adobe/css-tools"); | ||
const createParser = require("./less/parser"); | ||
const diff = require("./diff"); | ||
@@ -13,7 +12,6 @@ const scope = require("./scope"); | ||
// Plugins | ||
const ImportCollectorPlugin = require("./plugin/import-collector"); | ||
const VariableCollectorPlugin = require("./plugin/variable-collector"); | ||
const UrlCollector = require("./plugin/url-collector"); | ||
const Compiler = require("./Compiler"); | ||
const themingParametersDataUri = require("./themingParameters/dataUri"); | ||
// Workaround for a performance issue in the "css" parser module when used in combination | ||
@@ -108,3 +106,3 @@ // with the "colors" module that enhances the String prototype. | ||
/** | ||
* Creates a themebuild | ||
* Runs a theme build | ||
* @param {object} options | ||
@@ -120,6 +118,2 @@ * @param {object} options.compiler compiler object as passed to less | ||
// Stores mapping between "virtual" paths (used within LESS) and real filesystem paths. | ||
// Only relevant when using the "rootPaths" option. | ||
const mFileMappings = {}; | ||
// Assign default options | ||
@@ -149,212 +143,10 @@ options = Object.assign({ | ||
function fileHandler(file, currentFileInfo, handleDataAndCallCallback, callback) { | ||
let pathname; | ||
const compiler = new Compiler({ | ||
options, | ||
fileUtils: this.fileUtils, | ||
customFs: this.customFs | ||
}); | ||
// support absolute paths such as "/resources/my/base.less" | ||
if (path.posix.isAbsolute(file)) { | ||
pathname = path.posix.normalize(file); | ||
} else { | ||
pathname = path.posix.join(currentFileInfo.currentDirectory, file); | ||
} | ||
that.fileUtils.readFile(pathname, options.rootPaths).then(function(result) { | ||
if (!result) { | ||
// eslint-disable-next-line no-console | ||
console.log("File not found: " + pathname); | ||
callback({type: "File", message: "Could not find file at path '" + pathname + "'"}); | ||
} else { | ||
try { | ||
// Save import mapping to calculate full import paths later on | ||
mFileMappings[currentFileInfo.rootFilename] = mFileMappings[currentFileInfo.rootFilename] || {}; | ||
mFileMappings[currentFileInfo.rootFilename][pathname] = result.path; | ||
handleDataAndCallCallback(pathname, result.content); | ||
} catch (e) { | ||
// eslint-disable-next-line no-console | ||
console.log(e); | ||
callback(e); | ||
} | ||
} | ||
}, function(err) { | ||
// eslint-disable-next-line no-console | ||
console.log(err); | ||
callback(err); | ||
}); | ||
} | ||
function compile(config) { | ||
const parserOptions = clone(options.parser); | ||
let rootpath; | ||
if (config.path) { | ||
// Keep rootpath for later usage in the ImportCollectorPlugin | ||
rootpath = config.path; | ||
parserOptions.filename = config.localPath; | ||
} | ||
// inject the library name as prefix (e.g. "sap.m" as "_sap_m") | ||
if (options.library && typeof options.library.name === "string") { | ||
const libName = config.libName = options.library.name; | ||
config.libPath = libName.replace(/\./g, "/"); | ||
config.prefix = "_" + libName.replace(/\./g, "_") + "_"; | ||
} else { | ||
config.prefix = ""; // no library, no prefix | ||
} | ||
// Keep filename for later usage (see ImportCollectorPlugin) as less modifies the parserOptions.filename | ||
const filename = parserOptions.filename; | ||
// Only use custom file handler when "rootPaths" or custom "fs" are used | ||
let fnFileHandler; | ||
if ((options.rootPaths && options.rootPaths.length > 0) || that.customFs) { | ||
fnFileHandler = fileHandler; | ||
} | ||
const parser = createParser(parserOptions, fnFileHandler); | ||
return new Promise(function(resolve, reject) { | ||
parser.parse(config.content, function(err, tree) { | ||
if (err) { | ||
reject(err); | ||
} else { | ||
resolve(tree); | ||
} | ||
}); | ||
}).then(async function(tree) { | ||
const result = {}; | ||
result.tree = tree; | ||
// plugins to collect imported files and variable values | ||
const oImportCollector = new ImportCollectorPlugin({ | ||
importMappings: mFileMappings[filename] | ||
}); | ||
const oVariableCollector = new VariableCollectorPlugin(options.compiler); | ||
const oUrlCollector = new UrlCollector(); | ||
// render to css | ||
result.css = tree.toCSS(Object.assign({}, options.compiler, { | ||
plugins: [oImportCollector, oVariableCollector, oUrlCollector] | ||
})); | ||
// retrieve imported files | ||
result.imports = oImportCollector.getImports(); | ||
// retrieve reduced set of variables | ||
result.variables = oVariableCollector.getVariables(Object.keys(mFileMappings[filename] || {})); | ||
// retrieve all variables | ||
result.allVariables = oVariableCollector.getAllVariables(); | ||
// also compile rtl-version if requested | ||
let oRTL; | ||
if (options.rtl) { | ||
const RTLPlugin = require("./plugin/rtl"); | ||
oRTL = new RTLPlugin(); | ||
const urls = oUrlCollector.getUrls(); | ||
const existingImgRtlUrls = (await Promise.all( | ||
urls.map(async ({currentDirectory, relativeUrl}) => { | ||
const relativeImgRtlUrl = RTLPlugin.getRtlImgUrl(relativeUrl); | ||
if (relativeImgRtlUrl) { | ||
const resolvedImgRtlUrl = path.posix.join(currentDirectory, relativeImgRtlUrl); | ||
if (await that.fileUtils.findFile(resolvedImgRtlUrl, options.rootPaths)) { | ||
return resolvedImgRtlUrl; | ||
} | ||
} | ||
}) | ||
)).filter(Boolean); | ||
oRTL.setExistingImgRtlPaths(existingImgRtlUrls); | ||
} | ||
if (oRTL) { | ||
result.cssRtl = tree.toCSS(Object.assign({}, options.compiler, { | ||
plugins: [oRTL] | ||
})); | ||
} | ||
if (rootpath) { | ||
result.imports.unshift(rootpath); | ||
} | ||
// also compile css-variables version if requested | ||
if (options.cssVariables) { | ||
return new Promise(function(resolve, reject) { | ||
// parse the content again to have a clean tree | ||
parser.parse(config.content, function(err, tree) { | ||
if (err) { | ||
reject(err); | ||
} else { | ||
resolve(tree); | ||
} | ||
}); | ||
}).then(function(tree) { | ||
// generate the skeleton-css and the less-variables | ||
const CSSVariablesCollectorPlugin = require("./plugin/css-variables-collector"); | ||
const oCSSVariablesCollector = new CSSVariablesCollectorPlugin(config); | ||
const oVariableCollector = new VariableCollectorPlugin(options.compiler); | ||
result.cssSkeleton = tree.toCSS(Object.assign({}, options.compiler, { | ||
plugins: [oCSSVariablesCollector, oVariableCollector] | ||
})); | ||
const varsOverride = oVariableCollector.getAllVariables(); | ||
result.cssVariablesSource = oCSSVariablesCollector.toLessVariables(varsOverride); | ||
if (oRTL) { | ||
const oCSSVariablesCollectorRTL = new CSSVariablesCollectorPlugin(config); | ||
result.cssSkeletonRtl = tree.toCSS(Object.assign({}, options.compiler, { | ||
plugins: [oCSSVariablesCollectorRTL, oRTL] | ||
})); | ||
} | ||
return tree; | ||
}).then(function(tree) { | ||
// generate the css-variables content out of the less-variables | ||
return new Promise(function(resolve, reject) { | ||
parser.parse(result.cssVariablesSource, function(err, tree) { | ||
if (err) { | ||
reject(err); | ||
} else { | ||
const CSSVariablesPointerPlugin = require("./plugin/css-variables-pointer"); | ||
result.cssVariables = tree.toCSS(Object.assign({}, options.compiler, { | ||
plugins: [new CSSVariablesPointerPlugin()] | ||
})); | ||
resolve(result); | ||
} | ||
}); | ||
}); | ||
}); | ||
} | ||
return result; | ||
}); | ||
} | ||
function addInlineParameters(result) { | ||
return new Promise(function(resolve, reject) { | ||
if (typeof options.library === "object" && typeof options.library.name === "string") { | ||
const parameters = JSON.stringify(result.variables); | ||
// properly escape the parameters to be part of a data-uri | ||
// + escaping single quote (') as it is used to surround the data-uri: url('...') | ||
const escapedParameters = encodeURIComponent(parameters).replace(/'/g, function(char) { | ||
return escape(char); | ||
}); | ||
// embed parameter variables as plain-text string into css | ||
const parameterStyleRule = "\n/* Inline theming parameters */\n#sap-ui-theme-" + | ||
options.library.name.replace(/\./g, "\\.") + | ||
"{background-image:url('data:text/plain;utf-8," + escapedParameters + "')}\n"; | ||
// embed parameter variables as plain-text string into css | ||
result.css += parameterStyleRule; | ||
if (options.rtl) { | ||
result.cssRtl += parameterStyleRule; | ||
} | ||
if (options.cssVariables) { | ||
// for the css variables build we just add it to the variables | ||
result.cssVariables += parameterStyleRule; | ||
} | ||
} | ||
resolve(result); | ||
}); | ||
return themingParametersDataUri.addInlineParameters({result, options}); | ||
} | ||
@@ -392,3 +184,3 @@ | ||
} | ||
return compile(config); | ||
return compiler.compile(config); | ||
}), | ||
@@ -399,3 +191,3 @@ that.fileUtils.readFile(scopeOptions.embeddedFilePath, options.rootPaths).then(function(config) { | ||
} | ||
return compile(config); | ||
return compiler.compile(config); | ||
}) | ||
@@ -542,3 +334,5 @@ ]).then(function(results) { | ||
// No css diffing and scoping | ||
return that.fileUtils.readFile(options.lessInputPath, options.rootPaths).then(compile); | ||
return that.fileUtils.readFile(options.lessInputPath, options.rootPaths).then((config) => { | ||
return compiler.compile(config); | ||
}); | ||
}); | ||
@@ -556,3 +350,3 @@ } | ||
if (options.lessInput) { | ||
return compile({ | ||
return compiler.compile({ | ||
content: options.lessInput | ||
@@ -559,0 +353,0 @@ }).then(addInlineParameters).then(that.cacheTheme.bind(that)); |
@@ -47,30 +47,27 @@ "use strict"; | ||
const vars = {}; | ||
Object.keys(this.vars).forEach((key) => { | ||
const override = this.vars[key].updateAfterEval && varsOverride[key] !== undefined; | ||
/* | ||
if (override) { | ||
console.log(`Override variable "${key}" from "${this.vars[key].css}" to "${varsOverride[key]}"`); | ||
} | ||
*/ | ||
vars[key] = { | ||
css: override ? varsOverride[key] : this.vars[key].css, | ||
export: this.vars[key].export | ||
Object.keys(this.vars).forEach((variableName) => { | ||
const override = this.vars[variableName].updateAfterEval && varsOverride[variableName] !== undefined; | ||
vars[variableName] = { | ||
css: override ? varsOverride[variableName] : this.vars[variableName].css, | ||
export: this.vars[variableName].export | ||
}; | ||
}); | ||
let lessVariables = ""; | ||
Object.keys(vars).forEach((value, index) => { | ||
lessVariables += "@" + value + ": " + vars[value].css + ";\n"; | ||
Object.keys(vars).forEach((variableName) => { | ||
const variableValue = vars[variableName].css; | ||
lessVariables += `@${variableName}: ${variableValue};\n`; | ||
}); | ||
Object.keys(this.calcVars).forEach((value, index) => { | ||
lessVariables += "@" + value + ": " + this.calcVars[value].css + ";\n"; | ||
Object.keys(this.calcVars).forEach((variableName) => { | ||
const variableValue = this.calcVars[variableName].css; | ||
lessVariables += `@${variableName}: ${variableValue};\n`; | ||
}); | ||
lessVariables += "\n:root {\n"; | ||
Object.keys(vars).forEach((value, index) => { | ||
if (vars[value].export) { | ||
lessVariables += "--" + value + ": @" + value + ";\n"; | ||
Object.keys(vars).forEach((variableName) => { | ||
if (vars[variableName].export) { | ||
lessVariables += `--${variableName}: @${variableName};\n`; | ||
} | ||
}); | ||
Object.keys(this.calcVars).forEach((value, index) => { | ||
if (this.calcVars[value].export) { | ||
lessVariables += "--" + value + ": @" + value + ";\n"; | ||
Object.keys(this.calcVars).forEach((variableName) => { | ||
if (this.calcVars[variableName].export) { | ||
lessVariables += `--${variableName}: @${variableName};\n`; | ||
} | ||
@@ -77,0 +74,0 @@ }); |
{ | ||
"name": "less-openui5", | ||
"version": "0.11.2", | ||
"version": "0.11.3", | ||
"description": "Build OpenUI5 themes with Less.js", | ||
@@ -26,4 +26,4 @@ "author": { | ||
"lint": "eslint ./", | ||
"unit": "mocha test/*.js", | ||
"unit-debug": "mocha --inspect --inspect-brk test/*.js", | ||
"unit": "mocha test/*.js test/lib/**", | ||
"unit-debug": "mocha --inspect --inspect-brk test/*.js test/lib/**", | ||
"coverage": "nyc npm run unit", | ||
@@ -56,6 +56,6 @@ "test": "npm run lint && npm run coverage && npm run depcheck", | ||
"check-coverage": true, | ||
"statements": 90, | ||
"statements": 95, | ||
"branches": 85, | ||
"functions": 90, | ||
"lines": 90, | ||
"functions": 100, | ||
"lines": 95, | ||
"watermarks": { | ||
@@ -87,15 +87,15 @@ "statements": [ | ||
"dependencies": { | ||
"clone": "^2.1.0", | ||
"css": "^3.0.0", | ||
"@adobe/css-tools": "^4.0.1", | ||
"clone": "^2.1.2", | ||
"mime": "^1.6.0" | ||
}, | ||
"devDependencies": { | ||
"depcheck": "^1.4.2", | ||
"eslint": "^7.29.0", | ||
"depcheck": "^1.4.3", | ||
"eslint": "^7.32.0", | ||
"eslint-config-google": "^0.14.0", | ||
"graceful-fs": "^4.2.6", | ||
"graceful-fs": "^4.2.10", | ||
"mocha": "^8.4.0", | ||
"nyc": "^15.1.0", | ||
"sinon": "^10.0.0" | ||
"sinon": "^11.1.2" | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
63
359972
+ Added@adobe/css-tools@^4.0.1
+ Added@adobe/css-tools@4.4.1(transitive)
- Removedcss@^3.0.0
- Removedatob@2.1.2(transitive)
- Removedcss@3.0.0(transitive)
- Removeddecode-uri-component@0.2.2(transitive)
- Removedinherits@2.0.4(transitive)
- Removedsource-map@0.6.1(transitive)
- Removedsource-map-resolve@0.6.0(transitive)
Updatedclone@^2.1.2