Repository: remarkablemark/html-react-parser
Pull request #277 (2021-09-07 04:38:28)

feat: upgrade `react-property` to get react-dom 17 DOM/SVG properties
Relates to https://github.com/remarkablemark/react-dom-core/issues/14

## What is the motivation for this pull request?

feat: upgrade `react-property` to get react-dom 17 DOM/SVG properties

## What is the current behavior?

Uses DOM/SVG properties from react-dom 15

## What is the new behavior?

Uses DOM/SVG properties from react-dom 17

## Checklist:

- [x] Tests


Patch:
diff --git a/lib/attributes-to-props.js b/lib/attributes-to-props.js
index e2a52ab..186db4b 100644
--- a/lib/attributes-to-props.js
+++ b/lib/attributes-to-props.js
@@ -1,21 +1,20 @@
 var reactProperty = require('react-property');
 var utilities = require('./utilities');
 
-var hasOwnProperty = Object.prototype.hasOwnProperty;
-
 /**
  * Converts HTML/SVG DOM attributes to React props.
  *
  * @param  {object} [attributes={}] - HTML/SVG DOM attributes.
  * @return {object}                 - React props.
  */
-function attributesToProps(attributes) {
+module.exports = function attributesToProps(attributes) {
   attributes = attributes || {};
 
   var attributeName;
   var attributeNameLowerCased;
   var attributeValue;
-  var property;
+  var propName;
+  var propertyInfo;
   var props = {};
 
   for (attributeName in attributes) {
@@ -27,22 +26,23 @@ function attributesToProps(attributes) {
       continue;
     }
 
-    // convert HTML attribute to React prop
+    // convert HTML/SVG attribute to React prop
     attributeNameLowerCased = attributeName.toLowerCase();
-    if (hasOwnProperty.call(reactProperty.html, attributeNameLowerCased)) {
-      property = reactProperty.html[attributeNameLowerCased];
-      props[property.propertyName] =
-        property.hasBooleanValue ||
-        (property.hasOverloadedBooleanValue && !attributeValue)
-          ? true
-          : attributeValue;
-      continue;
-    }
-
-    // convert SVG attribute to React prop
-    if (hasOwnProperty.call(reactProperty.svg, attributeName)) {
-      property = reactProperty.svg[attributeName];
-      props[property.propertyName] = attributeValue;
+    propName = reactProperty.possibleStandardNames[attributeNameLowerCased];
+
+    if (propName) {
+      props[propName] = attributeValue;
+      propertyInfo = reactProperty.getPropertyInfo(propName);
+      switch (propertyInfo && propertyInfo.type) {
+        case reactProperty.BOOLEAN:
+          props[propName] = true;
+          break;
+        case reactProperty.OVERLOADED_BOOLEAN:
+          if (attributeValue === '') {
+            props[propName] = true;
+          }
+          break;
+      }
       continue;
     }
 
@@ -56,6 +56,4 @@ function attributesToProps(attributes) {
   utilities.setStyleProp(attributes.style, props);
 
   return props;
-}
-
-module.exports = attributesToProps;
+};
diff --git a/package.json b/package.json
index 39576f0..e38a298 100644
--- a/package.json
+++ b/package.json
@@ -39,7 +39,7 @@
   "dependencies": {
     "domhandler": "4.2.2",
     "html-dom-parser": "1.0.2",
-    "react-property": "1.0.2",
+    "react-property": "2.0.0",
     "style-to-js": "1.1.0"
   },
   "devDependencies": {


Test patch:
diff --git a/test/__snapshots__/attributes-to-props.test.js.snap b/test/__snapshots__/attributes-to-props.test.js.snap
index ab7cdc3..9536352 100644
--- a/test/__snapshots__/attributes-to-props.test.js.snap
+++ b/test/__snapshots__/attributes-to-props.test.js.snap
@@ -35,6 +35,7 @@ Object {
   "controls": true,
   "default": true,
   "disabled": true,
+  "draggable": "false",
   "formNoValidate": true,
   "hidden": true,
   "ismap": "",
@@ -42,8 +43,8 @@ Object {
   "loop": true,
   "multiple": true,
   "muted": true,
+  "noModule": true,
   "noValidate": true,
-  "nomodule": "",
   "open": true,
   "playsInline": true,
   "readOnly": true,
@@ -88,21 +89,12 @@ Object {
 }
 `;
 
-exports[`attributesToProps with SVG attribute keeps incorrectly capitalized attributes 1`] = `
-Object {
-  "XLINK:HREF": "#",
-  "YChannelSelector": "G",
-  "ZoomAndPan": "disable",
-}
-`;
-
 exports[`attributesToProps with custom attribute converts attributes named after Object properties 1`] = `
 Object {
   "__defineGetter__": "",
   "__defineSetter__": "",
   "__lookupGetter__": "",
   "__lookupSetter__": "",
-  "constructor": "",
   "hasOwnProperty": "",
   "isPrototypeOf": "",
   "propertyIsEnumerable": "",
diff --git a/test/attributes-to-props.test.js b/test/attributes-to-props.test.js
index 648d593..7ac762c 100644
--- a/test/attributes-to-props.test.js
+++ b/test/attributes-to-props.test.js
@@ -75,6 +75,7 @@ describe('attributesToProps with HTML attribute', () => {
       checked: 'true',
       controls: '',
       default: '',
+      draggable: 'false',
       disabled: 'disabled',
       formnovalidate: 'true',
       hidden: 'true',
@@ -118,13 +119,22 @@ describe('attributesToProps with SVG attribute', () => {
     expect(attributesToProps(attributes)).toMatchSnapshot();
   });
 
-  it('keeps incorrectly capitalized attributes', () => {
+  /**
+   * SVG elements and attributes should all be entered in the case shown here since XML is case-sensitive (unlike HTML).
+   *
+   * @see {@link https://developer.mozilla.org/docs/Web/SVG/Tutorial/Introduction#before_you_start}
+   */
+  it('fixes incorrectly capitalized attributes', () => {
     const attributes = {
       'XLINK:HREF': '#',
       YChannelSelector: 'G',
       ZoomAndPan: 'disable'
     };
-    expect(attributesToProps(attributes)).toMatchSnapshot();
+    expect(attributesToProps(attributes)).toEqual({
+      xlinkHref: '#',
+      yChannelSelector: 'G',
+      zoomAndPan: 'disable'
+    });
   });
 });
 
@@ -164,7 +174,6 @@ describe('attributesToProps with custom attribute', () => {
       __lookupGetter__: '',
       __lookupSetter__: '',
       __proto__: '',
-      constructor: '',
       hasOwnProperty: '',
       isPrototypeOf: '',
       propertyIsEnumerable: '',
@@ -194,13 +203,4 @@ describe('utilities.PRESERVE_CUSTOM_ATTRIBUTES=false', () => {
     };
     expect(attributesToProps(attributes)).toEqual(emptyProps);
   });
-
-  it('omits incorrectly capitalized attributes', () => {
-    const attributes = {
-      'XLINK:HREF': '#',
-      YChannelSelector: 'G',
-      ZoomAndPan: 'disable'
-    };
-    expect(attributesToProps(attributes)).toEqual(emptyProps);
-  });
 });