Repository: remarkablemark/html-react-parser
Pull request #187 (2020-12-11 02:08:37)

refactor(utilities): create `setStyleProp` helper from `styleToJS`
## What is the motivation for this pull request?

refactor(utilities): create `setStyleProp` helper from `styleToJS`, add tests

## Checklist:

- [x] Tests



Patch:
diff --git a/lib/attributes-to-props.js b/lib/attributes-to-props.js
index eb08cba..d2e3ff3 100644
--- a/lib/attributes-to-props.js
+++ b/lib/attributes-to-props.js
@@ -1,20 +1,19 @@
 var reactProperty = require('react-property');
-var styleToJS = require('style-to-js').default;
 var utilities = require('./utilities');
 
+var setStyleProp = utilities.setStyleProp;
+
 var htmlProperties = reactProperty.html;
 var svgProperties = reactProperty.svg;
 var isCustomAttribute = reactProperty.isCustomAttribute;
 
 var hasOwnProperty = Object.prototype.hasOwnProperty;
 
-var styleToJSOptions = { reactCompat: true };
-
 /**
  * Converts HTML/SVG DOM attributes to React props.
  *
- * @param  {Object} [attributes={}] - The HTML/SVG DOM attributes.
- * @return {Object}                 - The React props.
+ * @param  {object} [attributes={}] - HTML/SVG DOM attributes.
+ * @return {object}                 - React props.
  */
 function attributesToProps(attributes) {
   attributes = attributes || {};
@@ -59,10 +58,8 @@ function attributesToProps(attributes) {
     }
   }
 
-  // convert inline style to object
-  if (attributes.style != null) {
-    props.style = styleToJS(attributes.style, styleToJSOptions);
-  }
+  // transform inline style to object
+  setStyleProp(attributes.style, props);
 
   return props;
 }
diff --git a/lib/utilities.js b/lib/utilities.js
index 892850f..941d2bf 100644
--- a/lib/utilities.js
+++ b/lib/utilities.js
@@ -1,4 +1,5 @@
 var React = require('react');
+var styleToJS = require('style-to-js').default;
 
 /**
  * Swap key with value in an object.
@@ -70,8 +71,23 @@ function isCustomComponent(tagName, props) {
   }
 }
 
+var styleToJSOptions = { reactCompat: true };
+
+/**
+ * Sets style prop.
+ *
+ * @param {null|undefined|string} style
+ * @param {object} props
+ */
+function setStyleProp(style, props) {
+  if (style === null || style === undefined) {
+    return;
+  }
+  props.style = styleToJS(style, styleToJSOptions);
+}
+
 /**
- * @constant {Boolean}
+ * @constant {boolean}
  * @see {@link https://reactjs.org/blog/2017/09/08/dom-attributes-in-react-16.html}
  */
 var PRESERVE_CUSTOM_ATTRIBUTES = React.version.split('.')[0] >= 16;
@@ -79,5 +95,6 @@ var PRESERVE_CUSTOM_ATTRIBUTES = React.version.split('.')[0] >= 16;
 module.exports = {
   PRESERVE_CUSTOM_ATTRIBUTES: PRESERVE_CUSTOM_ATTRIBUTES,
   invertObject: invertObject,
-  isCustomComponent: isCustomComponent
+  isCustomComponent: isCustomComponent,
+  setStyleProp: setStyleProp
 };


Test patch:
diff --git a/test/__snapshots__/utilities.test.js.snap b/test/__snapshots__/utilities.test.js.snap
new file mode 100644
index 0000000..ed75f66
--- /dev/null
+++ b/test/__snapshots__/utilities.test.js.snap
@@ -0,0 +1,15 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`setStyleProp sets props.style 1`] = `
+Object {
+  "style": Object {
+    "WebkitUserSelect": "none",
+    "backgroundColor": "#bada55",
+    "backgroundImage": "linear-gradient(to bottom, rgba(255,255,0,0.5), rgba(0,0,255,0.5)),
+        url('https://mdn.mozillademos.org/files/7693/catfront.png')",
+    "color": "red",
+    "lineHeight": "1",
+  },
+  "width": 100,
+}
+`;
diff --git a/test/attributes-to-props.test.js b/test/attributes-to-props.test.js
index 6d7f4ec..648d593 100644
--- a/test/attributes-to-props.test.js
+++ b/test/attributes-to-props.test.js
@@ -1,6 +1,10 @@
 const attributesToProps = require('../lib/attributes-to-props');
 const utilities = require('../lib/utilities');
 
+it('returns empty object is argument is undefined', () => {
+  expect(attributesToProps()).toEqual({});
+});
+
 describe('attributesToProps with HTML attribute', () => {
   it('converts attributes to React props', () => {
     const attributes = {
diff --git a/test/utilities.test.js b/test/utilities.test.js
index aeaab5f..f90ac99 100644
--- a/test/utilities.test.js
+++ b/test/utilities.test.js
@@ -2,7 +2,8 @@ const React = require('react');
 const {
   PRESERVE_CUSTOM_ATTRIBUTES,
   invertObject,
-  isCustomComponent
+  isCustomComponent,
+  setStyleProp
 } = require('../lib/utilities');
 
 describe('invertObject', () => {
@@ -91,3 +92,29 @@ describe('PRESERVE_CUSTOM_ATTRIBUTES', () => {
     expect(PRESERVE_CUSTOM_ATTRIBUTES).toBe(isReactGreaterThan15);
   });
 });
+
+describe('setStyleProp', () => {
+  it.each([undefined, null])(
+    'does not set props.style when style=%p',
+    style => {
+      const props = {};
+      expect(setStyleProp(style, props)).toBe(undefined);
+      expect(props).toEqual({});
+    }
+  );
+
+  it('sets props.style', () => {
+    const style = `
+      color: red;
+      background-color: #bada55;
+      -webkit-user-select: none;
+      line-height: 1;
+      background-image:
+        linear-gradient(to bottom, rgba(255,255,0,0.5), rgba(0,0,255,0.5)),
+        url('https://mdn.mozillademos.org/files/7693/catfront.png');
+    `;
+    const props = { style: { foo: 'bar' }, width: 100 };
+    expect(setStyleProp(style, props)).toBe(undefined);
+    expect(props).toMatchSnapshot();
+  });
+});