Skip to content

Commit 4d69410

Browse files
committed
Rewrite
1 parent 077b6d7 commit 4d69410

File tree

19 files changed

+1897
-458
lines changed

19 files changed

+1897
-458
lines changed

.babelrc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"presets": ["es2015-loose", "stage-0"],
3+
"plugins": ["add-module-exports"],
4+
"env": {
5+
"development": {
6+
"sourceMaps": "inline"
7+
},
8+
"test": {
9+
"plugins": ["istanbul"]
10+
}
11+
}
12+
}

.eslintrc

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
---
2+
parser: babel-eslint
3+
plugins:
4+
- babel
5+
- import
6+
7+
root: true
8+
extends: eslint:recommended
9+
10+
#ecmaFeatures:
11+
# modules: true
12+
13+
env:
14+
es6: true
15+
browser: true
16+
node: true
17+
18+
rules:
19+
# babel/object-curly-spacing: [2]
20+
# brace-style: [2, 1tbs, {allowSingleLine: false}]
21+
camelcase: [2]
22+
# comma-dangle: [2, always-multiline]
23+
comma-spacing: [2]
24+
curly: [error, multi-or-nest]
25+
dot-notation: [2]
26+
eol-last: [2]
27+
eqeqeq: [2]
28+
handle-callback-err: [2]
29+
import/export: [2]
30+
import/imports-first: [2]
31+
import/named: [2]
32+
import/namespace: [2, {allowComputed: true}]
33+
import/newline-after-import: [2]
34+
import/no-duplicates: [2]
35+
import/no-mutable-exports: [2]
36+
import/no-named-as-default: [2]
37+
import/no-named-as-default-member: [2]
38+
# import/no-unresolved: [2, {"commonjs": true}]
39+
import/order: [2]
40+
import/prefer-default-export: [2]
41+
indent: [2, 2, { "SwitchCase": 1 }]
42+
keyword-spacing: [2]
43+
new-cap: [2]
44+
new-parens: [2]
45+
no-alert: [2]
46+
no-caller: [2]
47+
no-case-declarations: [0]
48+
no-const-assign: [2]
49+
no-constant-condition: [2]
50+
no-dupe-args: [2]
51+
no-dupe-keys: [2]
52+
no-empty: [2]
53+
no-empty-character-class: [2]
54+
no-eval: [2]
55+
no-irregular-whitespace: [2]
56+
no-labels: [2]
57+
no-lonely-if: [2]
58+
no-multiple-empty-lines: [2]
59+
no-new: [2]
60+
no-octal: [2]
61+
no-proto: [2]
62+
no-redeclare: [2]
63+
no-return-assign: [2]
64+
no-self-assign: [2]
65+
no-self-compare: [2]
66+
no-shadow: [2]
67+
no-shadow-restricted-names: [2]
68+
no-sparse-arrays: [2]
69+
no-undef: [2]
70+
no-unreachable: [2]
71+
no-unused-vars: [2]
72+
no-useless-call: [2]
73+
no-var: [2]
74+
no-void: [2]
75+
no-warning-comments: [2]
76+
no-with: [2]
77+
quote-props: [2, as-needed]
78+
prefer-arrow-callback: [2]
79+
radix: [2]
80+
semi: [2, always]
81+
semi-spacing: [2]
82+
# space-before-function-paren: [2, always]
83+
space-before-blocks: [2, always]
84+
spaced-comment: [2, always]
85+
strict: [2, global]
86+
yoda: [2, never]

.jscsrc

Lines changed: 0 additions & 130 deletions
This file was deleted.

.jshintrc

Lines changed: 0 additions & 11 deletions
This file was deleted.

dist/__tests__/index.js

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
'use strict';
2+
3+
var _ava = require('ava');
4+
5+
var _ava2 = _interopRequireDefault(_ava);
6+
7+
var _ = require('..');
8+
9+
var _2 = _interopRequireDefault(_);
10+
11+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12+
13+
function testFixture(t, fixture) {
14+
var expected = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
15+
var precision = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 5;
16+
17+
if (expected === null) expected = fixture;
18+
19+
var out = (0, _2.default)(fixture, precision);
20+
t.deepEqual(out, expected);
21+
}
22+
23+
function testThrows(t, fixture, expected) {
24+
var precision = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 5;
25+
26+
t.throws(function () {
27+
return (0, _2.default)(fixture, precision);
28+
}, expected);
29+
}
30+
31+
(0, _ava2.default)('should reduce simple calc (1)', testFixture, 'calc(1px + 1px)', '2px');
32+
33+
(0, _ava2.default)('should reduce simple calc (2)', testFixture, 'calc(3em - 1em)', '2em');
34+
35+
(0, _ava2.default)('should reduce simple calc (3)', testFixture, 'calc(1rem * 1.5)', '1.5rem');
36+
37+
(0, _ava2.default)('should reduce simple calc (4)', testFixture, 'calc(2ex / 2)', '1ex');
38+
39+
(0, _ava2.default)('should ignore value surrounding calc function (1)', testFixture, 'a calc(1px + 1px)', 'a 2px');
40+
41+
(0, _ava2.default)('should ignore value surrounding calc function (2)', testFixture, 'calc(1px + 1px) a', '2px a');
42+
43+
(0, _ava2.default)('should ignore value surrounding calc function (3)', testFixture, 'a calc(1px + 1px) b', 'a 2px b');
44+
45+
(0, _ava2.default)('should ignore value surrounding calc function (4)', testFixture, 'a calc(1px + 1px) b calc(1em + 2em) c', 'a 2px b 3em c');
46+
47+
(0, _ava2.default)('should reduce calc with newline characters', testFixture, 'calc(\n1rem \n* 2 \n* 1.5)', '3rem');
48+
49+
(0, _ava2.default)('should preserve calc with incompatible units', testFixture, 'calc(100% + 1px)', 'calc(100% + 1px)');
50+
51+
(0, _ava2.default)('should parse fractions without leading zero', testFixture, 'calc(2rem - .14285em)', 'calc(2rem - 0.14285em)');
52+
53+
(0, _ava2.default)('should handle precision correctly (1)', testFixture, 'calc(1/100)', '0.01');
54+
55+
(0, _ava2.default)('should handle precision correctly (2)', testFixture, 'calc(5/1000000)', '0.00001');
56+
57+
(0, _ava2.default)('should handle precision correctly (3)', testFixture, 'calc(5/1000000)', '0.000005', 6);
58+
59+
(0, _ava2.default)('should reduce browser-prefixed calc (1)', testFixture, '-webkit-calc(1px + 1px)', '2px');
60+
61+
(0, _ava2.default)('should reduce browser-prefixed calc (2)', testFixture, '-moz-calc(1px + 1px)', '2px');
62+
63+
(0, _ava2.default)('should discard zero values (#2) (1)', testFixture, 'calc(100vw / 2 - 6px + 0px)', 'calc(50vw - 6px)');
64+
65+
(0, _ava2.default)('should discard zero values (#2) (2)', testFixture, 'calc(500px - 0px)', '500px');
66+
67+
(0, _ava2.default)('should not perform addition on unitless values (#3)', testFixture, 'calc(1px + 1)', 'calc(1px + 1)');
68+
69+
(0, _ava2.default)('should produce simpler result (postcss-calc#25) (1)', testFixture, 'calc(14px + 6 * ((100vw - 320px) / 448))', 'calc(9.71px + 1.34vw)', 2);
70+
71+
(0, _ava2.default)('should produce simpler result (postcss-calc#25) (2)', testFixture, '-webkit-calc(14px + 6 * ((100vw - 320px) / 448))', '-webkit-calc(9.71px + 1.34vw)', 2);
72+
73+
(0, _ava2.default)('should reduce mixed units of time (postcss-calc#33)', testFixture, 'calc(1s - 50ms)', '0.95s');
74+
75+
(0, _ava2.default)('should correctly reduce calc with mixed units (cssnano#211)', testFixture, 'bar:calc(99.99% * 1/1 - 0rem)', 'bar:99.99%');
76+
77+
(0, _ava2.default)('should apply algebraic reduction (cssnano#319)', testFixture, 'bar:calc((100px - 1em) + (-50px + 1em))', 'bar:50px');
78+
79+
(0, _ava2.default)('should apply optimization (cssnano#320)', testFixture, 'bar:calc(50% + (5em + 5%))', 'bar:calc(55% + 5em)');
80+
81+
(0, _ava2.default)('should throw an exception when attempting to divide by zero', testThrows, 'calc(500px/0)', /Cannot divide by zero/);
82+
83+
(0, _ava2.default)('should throw an exception when attempting to divide by unit', testThrows, 'calc(500px/2px)', 'Cannot divide by "px", number expected');

dist/index.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
'use strict';
2+
3+
exports.__esModule = true;
4+
5+
var _postcssValueParser = require('postcss-value-parser');
6+
7+
var _postcssValueParser2 = _interopRequireDefault(_postcssValueParser);
8+
9+
var _parser = require('./parser');
10+
11+
var _reducer = require('./lib/reducer');
12+
13+
var _reducer2 = _interopRequireDefault(_reducer);
14+
15+
var _stringifier = require('./lib/stringifier');
16+
17+
var _stringifier2 = _interopRequireDefault(_stringifier);
18+
19+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20+
21+
var MATCH_CALC = /((?:\-[a-z]+\-)?calc)/;
22+
23+
exports.default = function (value) {
24+
var precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 5;
25+
26+
return (0, _postcssValueParser2.default)(value).walk(function (node) {
27+
// skip anything which isn't a calc() function
28+
if (node.type !== 'function' || !MATCH_CALC.test(node.value)) return;
29+
30+
// stringify calc expression and produce an AST
31+
var contents = _postcssValueParser2.default.stringify(node.nodes);
32+
var ast = _parser.parser.parse(contents);
33+
34+
// reduce AST to its simplest form, that is, either to a single value
35+
// or a simplified calc expression
36+
var reducedAst = (0, _reducer2.default)(ast, precision);
37+
38+
// stringify AST and write it back
39+
node.type = 'word';
40+
node.value = (0, _stringifier2.default)(node.value, reducedAst, precision);
41+
}, true).toString();
42+
};
43+
44+
module.exports = exports['default'];

0 commit comments

Comments
 (0)