diff --git a/lib/CSSStyleDeclaration.test.js b/lib/CSSStyleDeclaration.test.js index 9fa8ed3b..6e347112 100644 --- a/lib/CSSStyleDeclaration.test.js +++ b/lib/CSSStyleDeclaration.test.js @@ -553,4 +553,16 @@ describe('CSSStyleDeclaration', () => { style.setProperty('width', 'calc(100% - 100px)'); expect(style.getPropertyValue('width')).toEqual('calc(100% - 100px)'); }); + + test('supports var', () => { + const style = new CSSStyleDeclaration(); + style.setProperty('width', 'var(--value)'); + expect(style.getPropertyValue('width')).toEqual('var(--value)'); + }); + + test('supports color var', () => { + const style = new CSSStyleDeclaration(); + style.setProperty('color', 'var(--foo)'); + expect(style.getPropertyValue('color')).toEqual('var(--foo)'); + }); }); diff --git a/lib/parsers.js b/lib/parsers.js index 8ecdf5e3..e3cc854a 100644 --- a/lib/parsers.js +++ b/lib/parsers.js @@ -19,6 +19,7 @@ exports.TYPES = { KEYWORD: 9, NULL_OR_EMPTY_STR: 10, CALC: 11, + VARIABLE: 12 }; // rough regular expressions @@ -31,7 +32,8 @@ var stringRegEx = /^("[^"]*"|'[^']*')$/; var colorRegEx1 = /^#([0-9a-fA-F]{3,4}){1,2}$/; var colorRegEx2 = /^rgb\(([^)]*)\)$/; var colorRegEx3 = /^rgba\(([^)]*)\)$/; -var calcRegEx = /^calc\(([^)]*)\)$/; +var calcRegEx = /^calc\((.*)\)$/; +var variableRegEx = /^var\(--([^)]*)\)$/; var colorRegEx4 = /^hsla?\(\s*(-?\d+|-?\d*.\d+)\s*,\s*(-?\d+|-?\d*.\d+)%\s*,\s*(-?\d+|-?\d*.\d+)%\s*(,\s*(-?\d+|-?\d*.\d+)\s*)?\)/; var angleRegEx = /^([-+]?[0-9]*\.?[0-9]+)(deg|grad|rad)$/; @@ -66,6 +68,9 @@ exports.valueType = function valueType(val) { if (calcRegEx.test(val)) { return exports.TYPES.CALC; } + if (variableRegEx.test(val)) { + return exports.TYPES.VARIABLE; + } if (stringRegEx.test(val)) { return exports.TYPES.STRING; } @@ -208,7 +213,8 @@ exports.parsePercent = function parsePercent(val) { // either a length or a percent exports.parseMeasurement = function parseMeasurement(val) { var type = exports.valueType(val); - if (type === exports.TYPES.CALC) { + if (type === exports.TYPES.CALC || + type === exports.TYPES.VARIABLE) { return val; } @@ -287,7 +293,8 @@ exports.parseString = function parseString(val) { exports.parseColor = function parseColor(val) { var type = exports.valueType(val); - if (type === exports.TYPES.NULL_OR_EMPTY_STR) { + if (type === exports.TYPES.NULL_OR_EMPTY_STR + || type === exports.TYPES.VARIABLE) { return val; } var red, diff --git a/lib/parsers.test.js b/lib/parsers.test.js index 926f7e74..95daaee5 100644 --- a/lib/parsers.test.js +++ b/lib/parsers.test.js @@ -72,6 +72,20 @@ describe('valueType', () => { expect(output).toEqual(parsers.TYPES.CALC); }); + + it('returns calc from calc(100px * (6 - 4))', () => { + let input = 'calc(100px * (6 - 4))'; + let output = parsers.valueType(input); + + expect(output).toEqual(parsers.TYPES.CALC); + }); + + it('returns variable from var(--value)', () => { + let input = 'var(--value)'; + let output = parsers.valueType(input); + + expect(output).toEqual(parsers.TYPES.VARIABLE); + }); }); describe('parseInteger', () => { it.todo('test'); @@ -86,6 +100,55 @@ describe('parsePercent', () => { it.todo('test'); }); describe('parseMeasurement', () => { + it('accepts px', () => { + let input = '15px'; + let output = parsers.parseMeasurement(input); + + expect(output).toEqual('15px'); + }); + it('accepts percent', () => { + let input = '15%'; + let output = parsers.parseMeasurement(input); + + expect(output).toEqual('15%'); + }); + it('defaults to undefined', () => { + let input = '15'; + let output = parsers.parseMeasurement(input); + + expect(output).toEqual(undefined); + }); + it('accepts zero without unit', () => { + let input = '0'; + let output = parsers.parseMeasurement(input); + + expect(output).toEqual('0px'); + }); + it('rejects other unit', () => { + let input = '15deg'; + let output = parsers.parseMeasurement(input); + + expect(output).toEqual(undefined); + }); + it('keeps value definition starting with calc', () => { + let input = 'calc(100% / 4)'; + let output = parsers.parseMeasurement(input); + + expect(output).toEqual('calc(100% / 4)'); + }); + it('keeps value definition starting with var', () => { + let input = 'var(--value)'; + let output = parsers.parseMeasurement(input); + + expect(output).toEqual('var(--value)'); + }); + it('keeps value definition combining calc and var', () => { + let input = 'calc((20 - 18) * 2 * var(--value))'; + let output = parsers.parseMeasurement(input); + + expect(output).toEqual('calc((20 - 18) * 2 * var(--value))'); + }); + it.todo('test'); }); describe('parseUrl', () => { @@ -107,6 +170,12 @@ describe('parseColor', () => { expect(output).toEqual('rgba(5, 5, 5, 0.5)'); }); + it('should keep value definition when it starts with var', () => { + let input = 'var(--value)'; + let output = parsers.parseColor(input); + + expect(output).toEqual('var(--value)'); + }); it.todo('Add more tests'); });