Skip to content

Commit

Permalink
Add preserve option
Browse files Browse the repository at this point in the history
Setting `preserve` to `true` will preserve  `calc()` in the output, so
that they can be used by supporting browsers.
Useful now that browsers are starting to implement vars (eg Firefox
31+) & it’s even better for debug [to see real
rules](http://cl.ly/image/3W3O0E41173X).

I’ve refactored the code a little bit to make it easier to use the
`options.preserve` in the main function (& also use rework-visit which
is more bullet proof).

This should be a major update since now calc need to be called as a
function (like rework-vars for example) to be able to pass options. So
this should be tagged as 0.3 (or maybe it’s time to ship 1.0 :) ?)

I also quickly refactor tests to make it more understandable
(plugins.js near preserve.css was confusing imo).

I hope it’s ok.

FWI, I did this since I’m more seeing rework-vars & rework-calc as
fallback than replacement.
See reworkcss/rework-vars#28
reworkcss/rework-vars#29 &
segmentio/myth#64
  • Loading branch information
MoOx committed May 26, 2014
1 parent 9e41e96 commit 2268fd6
Show file tree
Hide file tree
Showing 15 changed files with 105 additions and 81 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ particularly useful together with the [rework-vars](https://npmjs.org/package/re
When multiple units are mixed together in the same expression, the calc() statement
is left as is, to fallback to the CSS3 Calc feature.

**Example** (with rework-vars enabled as well):
**Example** (with [rework-vars](https://github.com/reworkcss/rework-vars) enabled as well):

```css
:root {
Expand Down Expand Up @@ -62,6 +62,12 @@ h1 {

See unit tests for another example.

### Options

#### `preserve` (default: `false`)

Setting `preserve` to `true` will preserve `calc()` in the output, so that they can be used by supporting browsers.

## Unit tests

Make sure the dev-dependencies are installed, and then run:
Expand Down
70 changes: 37 additions & 33 deletions lib/calc.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@

/**
* Calculation Plugin
*
* Useful in combination with the [rework-vars](https://npmjs.org/package/rework-vars) plugin, e.g:
*
* :root {
* var-base-font-size: 16px;
* --base-font-size: 16px;
* }
* body {
* font-size: var(base-font-size);
* font-size: var(--base-font-size);
* }
* h1 {
* font-size: calc(var(base-font-size) * 2);
* font-size: calc(var(--base-font-size) * 2);
* }
*
* Yields:
*
* :root {
* var-base-font-size: 16px;
* }
* body {
* font-size: 16px;
* }
Expand All @@ -28,8 +24,35 @@
*
*/

module.exports = function (style) {
rules(style.rules);
var visit = require('rework-visit');

module.exports = function (options) {
options = options || {};
options.preserve = options.preserve !== undefined ? options.preserve : false;

return function calc(style) {
visit(style, !options.preserve ?
function(declarations, node) {
declarations.forEach(function (decl) {
if (!hasExpressions(decl.value)) return;

decl.value = evaluateValue(decl.value);
});
} :
function(declarations, node) {
for (var i = 0; i < declarations.length; i++) {
var decl = declarations[i]
if (!hasExpressions(decl.value)) return;

declarations.splice(i++, 0, {
type: decl.type,
property: decl.property,
value: evaluateValue(decl.value)
});
}
}
);
}
};

/**
Expand All @@ -41,34 +64,13 @@ var DEFAULT_UNIT = 'px',
EXPRESSION_METHOD_REGEXP = EXPRESSION_OPT_VENDOR_PREFIX + EXPRESSION_METHOD_NAME,
EXPRESSION_REGEXP = '\\b' + EXPRESSION_METHOD_REGEXP + '\\(';

/**
* Visit all rules
*
* @param {Array} arr Array with css rules
* @api private
*/
function rules(arr) {
arr.forEach(function (rule) {
if (rule.rules) rules(rule.rules);
if (rule.declarations) visit(rule.declarations);
});
}

/**
* Visit all declarations (in a rule)
*
* @param {Array} declarations
* @api private
*/
function visit(declarations) {
declarations.forEach(function (decl) {
if (!hasExpressions(decl.value)) return;

var expressions = getExpressionsFromValue(decl.value);

evaluateAndApplyExpressions(expressions, decl);
});
}

/**
* Checks if a value contains an expression
Expand Down Expand Up @@ -118,8 +120,8 @@ function getExpressionsFromValue(value) {
* @param {Object} declaration
* @api private
*/
function evaluateAndApplyExpressions(expressions, declaration) {
expressions.forEach(function (expression) {
function evaluateValue(value) {
getExpressionsFromValue(value).forEach(function (expression) {
var result = evaluateExpression(expression);

if (!result) return;
Expand All @@ -129,8 +131,10 @@ function evaluateAndApplyExpressions(expressions, declaration) {
EXPRESSION_METHOD_REGEXP + '\\(' +
escapeExp(expression) + '\\)'
);
declaration.value = declaration.value.replace(expRegexp, result);
value = value.replace(expRegexp, result);
});

return value
}

/**
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,8 @@
"mocha": "~1.15.1",
"rework": "~0.18.3",
"chai": "~1.8.1"
},
"dependencies": {
"rework-visit": "^1.0.0"
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
9 changes: 9 additions & 0 deletions test/fixtures/preserve.in.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

body {
width: 100%;
}

body > header {
height: calc(3em * 2);
font-size: calc(6em / 2);
}
11 changes: 11 additions & 0 deletions test/fixtures/preserve.out.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

body {
width: 100%;
}

body > header {
height: 6em;
height: calc(3em * 2);
font-size: 3em;
font-size: calc(6em / 2);
}
47 changes: 0 additions & 47 deletions test/plugins.js

This file was deleted.

38 changes: 38 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
var calc = require('../index'),
rework = require('rework'),
expect = require('chai').expect,
read = require('fs').readFileSync;

function fixture(name){
return read('test/fixtures/' + name + '.css', 'utf8').trim();
}

function compareFixtures(name, options){
return expect(
rework(fixture(name + '.in'))
.use(calc(options))
.toString().trim()
).to.equal(fixture(name + '.out'));
}

describe('rework-calc', function() {
it('should calculate expressions with only one unit involved', function() {
compareFixtures('calc');
});

it('should calculate expressions with percents correctly', function () {
compareFixtures('calc-percent');
});

it('should use CSS3 Calc function as fallback for expressions with multiple units', function () {
compareFixtures('calc-complex');
});

it('should handle vendor prefixed expressions', function () {
compareFixtures('calc-prefix');
});

it('should preserves calc() when `preserve` is `true`', function() {
compareFixtures('preserve', {preserve: true});
});
});

0 comments on commit 2268fd6

Please sign in to comment.