Skip to content

Commit

Permalink
[FEATURE] Add experimental CSS variables and skeleton build (#108)
Browse files Browse the repository at this point in the history
Co-authored-by: Tobias Sorn <tobias.sorn@web.de>
Co-authored-by: Matthias Oßwald <1410947+matz3@users.noreply.github.com>
  • Loading branch information
3 people committed Feb 10, 2020
1 parent 6622b5c commit e6d8503
Show file tree
Hide file tree
Showing 12 changed files with 449 additions and 8 deletions.
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ Default: `true`

Create mirrored css for right-to-left support.

##### cssVariables

Type `boolean`
Default: `false`

Create files for experimental CSS Variables support ([`cssSkeleton`](#cssSkeleton), [`cssSkeletonRtl`](#cssSkeletonRtl), [`cssVariablesSource`](#cssVariablesSource), [`cssVariables`](#cssVariables-1)).

##### rootPaths

Type: `array` of `string`
Expand Down Expand Up @@ -212,6 +219,34 @@ Type: `array`

Paths to files imported via import directives.

##### cssSkeleton

Type: `string`
Only available when [`options.cssVariables`](#cssVariables) is set to `true`

CSS with references to CSS Variables.

##### cssSkeletonRtl

Type: `string`
Only available when [`options.cssVariables`](#cssVariables) and [`options.rtl`](#rtl) are set to `true`

Mirrored (right-to-left) CSS with references to CSS Variables (if `rtl` option was enabled).

##### cssVariablesSource

Type: `string`
Only available when [`options.cssVariables`](#cssVariables) is set to `true`

Source file used to compile the `cssVariables` output.

##### cssVariables

Type: `string`
Only available when [`options.cssVariables`](#cssVariables) is set to `true`

Definition of CSS Variables based on LESS variables.

### .clearCache()
Clears all cached build results.
Use this method to prevent high memory consumption when building many themes within the same process.
Expand Down
86 changes: 80 additions & 6 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ const scope = require("./scope");
const fileUtilsFactory = require("./fileUtils");

// Plugins
const RTLPlugin = require("./plugin/rtl");
const ImportCollectorPlugin = require("./plugin/import-collector");
const VariableCollectorPlugin = require("./plugin/variable-collector");

Expand Down Expand Up @@ -118,6 +117,15 @@ Builder.prototype.cacheTheme = function(result) {
});
};

/**
* Creates a themebuild
* @param {object} options
* @param {object} options.compiler compiler object as passed to less
* @param {boolean} options.cssVariables whether or not to enable css variables output
* @param {string} options.lessInput less string input
* @param {string} options.lessInputPath less file input
* @returns {{css: string, cssRtl: string, variables: {}, imports: [], cssSkeleton: string, cssSkeletonRtl: string, cssVariables: string, cssVariablesSource: string }}
*/
Builder.prototype.build = function(options) {
const that = this;

Expand Down Expand Up @@ -162,7 +170,7 @@ Builder.prototype.build = function(options) {
that.fileUtils.readFile(pathname, options.rootPaths).then(function(result) {
if (!result) {
// eslint-disable-next-line no-console
console.log("File not found");
console.log("File not found: " + file);
callback({type: "File", message: "'" + file + "' wasn't found"});
} else {
try {
Expand Down Expand Up @@ -194,6 +202,12 @@ Builder.prototype.build = function(options) {
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.prefix = "_" + libName.replace(/\./g, "_") + "_";
}

// Keep filename for later usage (see ImportCollectorPlugin) as less modifies the parserOptions.filename
const filename = parserOptions.filename;

Expand All @@ -203,8 +217,9 @@ Builder.prototype.build = function(options) {
fnFileHandler = fileHandler;
}

const parser = createParser(parserOptions, fnFileHandler);

return new Promise(function(resolve, reject) {
const parser = createParser(parserOptions, fnFileHandler);
parser.parse(config.content, function(err, tree) {
if (err) {
reject(err);
Expand All @@ -224,7 +239,7 @@ Builder.prototype.build = function(options) {
const oVariableCollector = new VariableCollectorPlugin(options.compiler);

// render to css
result.css = tree.toCSS(assign(options.compiler, {
result.css = tree.toCSS(assign({}, options.compiler, {
plugins: [oImportCollector, oVariableCollector]
}));

Expand All @@ -238,16 +253,63 @@ Builder.prototype.build = function(options) {
result.allVariables = oVariableCollector.getAllVariables();

// also compile rtl-version if requested
let oRTL;
if (options.rtl) {
result.cssRtl = tree.toCSS(assign(options.compiler, {
plugins: [new RTLPlugin()]
const RTLPlugin = require("./plugin/rtl");
oRTL = new RTLPlugin();
}

if (oRTL) {
result.cssRtl = tree.toCSS(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);
result.cssSkeleton = tree.toCSS(assign({}, options.compiler, {
plugins: [oCSSVariablesCollector]
}));
result.cssVariablesSource = oCSSVariablesCollector.toLessVariables();
if (oRTL) {
const oCSSVariablesCollectorRTL = new CSSVariablesCollectorPlugin(config);
result.cssSkeletonRtl = tree.toCSS(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 {
result.cssVariables = tree.toCSS(assign({}, options.compiler));
resolve(result);
}
});
});
});
}

return result;
});
}
Expand All @@ -273,6 +335,10 @@ Builder.prototype.build = function(options) {
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);
});
Expand Down Expand Up @@ -359,6 +425,14 @@ Builder.prototype.build = function(options) {
results.embeddedCompare.cssRtl += applyScope(results.embeddedCompare.cssRtl, results.embedded.cssRtl, true);
}

if (options.cssVariables) {
results.embeddedCompare.cssVariables += applyScope(results.embeddedCompare.cssVariables, results.embedded.cssVariables);
results.embeddedCompare.cssSkeleton += applyScope(results.embeddedCompare.cssSkeleton, results.embedded.cssSkeleton);
if (options.rtl) {
results.embeddedCompare.cssSkeletonRtl += applyScope(results.embeddedCompare.cssSkeletonRtl, results.embedded.cssSkeletonRtl, true);
}
}

// Create diff between embeddedCompare and embeded variables
results.embeddedCompare.variables = getScopeVariables({
baseVariables: results.embeddedCompare.variables,
Expand Down

0 comments on commit e6d8503

Please sign in to comment.