Repository: jsdom/cssstyle (js)

Issue:
Doesn't support `calc`
```js
import cssstyle from "cssstyle";

export const stringifyCssText = (styleObject: object): string => {
  let cssText = "";
  const style = new cssstyle.CSSStyleDeclaration(newCssText => {
    cssText = newCssText;
  });
  Object.assign(style, styleObject);

  return cssText;
};
console.log(
  stringifyCssText({
    width: "100vh",
    height: "calc(100vh * 2)"
  })
);
// will output `width: 100vh;` but `height` is missing
```

Demo here https://codesandbox.io/s/flamboyant-moore-983md

Pull request:
Implement basic calc
This PR adds basic support for un-computed `calc()` values. 

Closes #100 

Patch:
diff --git a/lib/parsers.js b/lib/parsers.js
index 5bc92cd..8ecdf5e 100644
--- a/lib/parsers.js
+++ b/lib/parsers.js
@@ -18,6 +18,7 @@ exports.TYPES = {
   ANGLE: 8,
   KEYWORD: 9,
   NULL_OR_EMPTY_STR: 10,
+  CALC: 11,
 };
 
 // rough regular expressions
@@ -30,6 +31,7 @@ var stringRegEx = /^("[^"]*"|'[^']*')$/;
 var colorRegEx1 = /^#([0-9a-fA-F]{3,4}){1,2}$/;
 var colorRegEx2 = /^rgb\(([^)]*)\)$/;
 var colorRegEx3 = /^rgba\(([^)]*)\)$/;
+var calcRegEx = /^calc\(([^)]*)\)$/;
 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)$/;
 
@@ -61,6 +63,9 @@ exports.valueType = function valueType(val) {
   if (urlRegEx.test(val)) {
     return exports.TYPES.URL;
   }
+  if (calcRegEx.test(val)) {
+    return exports.TYPES.CALC;
+  }
   if (stringRegEx.test(val)) {
     return exports.TYPES.STRING;
   }
@@ -70,6 +75,7 @@ exports.valueType = function valueType(val) {
   if (colorRegEx1.test(val)) {
     return exports.TYPES.COLOR;
   }
+
   var res = colorRegEx2.exec(val);
   var parts;
   if (res !== null) {
@@ -201,6 +207,11 @@ 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) {
+    return val;
+  }
+
   var length = exports.parseLength(val);
   if (length !== undefined) {
     return length;


Test patch:
diff --git a/lib/CSSStyleDeclaration.test.js b/lib/CSSStyleDeclaration.test.js
index d0cba23..9fa8ed3 100644
--- a/lib/CSSStyleDeclaration.test.js
+++ b/lib/CSSStyleDeclaration.test.js
@@ -547,4 +547,10 @@ describe('CSSStyleDeclaration', () => {
     expect(style.getPropertyValue('--foo')).toEqual('');
     expect(style.getPropertyValue('--fOo')).toEqual('purple');
   });
+
+  test('supports calc', () => {
+    const style = new CSSStyleDeclaration();
+    style.setProperty('width', 'calc(100% - 100px)');
+    expect(style.getPropertyValue('width')).toEqual('calc(100% - 100px)');
+  });
 });
diff --git a/lib/parsers.test.js b/lib/parsers.test.js
index 1f57dfa..926f7e7 100644
--- a/lib/parsers.test.js
+++ b/lib/parsers.test.js
@@ -65,6 +65,13 @@ describe('valueType', () => {
 
     expect(output).toEqual(parsers.TYPES.LENGTH);
   });
+
+  it('returns calc from calc(100px * 2)', () => {
+    let input = 'calc(100px * 2)';
+    let output = parsers.valueType(input);
+
+    expect(output).toEqual(parsers.TYPES.CALC);
+  });
 });
 describe('parseInteger', () => {
   it.todo('test');