html-react-parser 1.4.1 → 1.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,12 +10,18 @@ var utilities = require('./utilities');
10
10
  module.exports = function attributesToProps(attributes) {
11
11
  attributes = attributes || {};
12
12
 
13
+ var valueOnlyInputs = {
14
+ reset: true,
15
+ submit: true
16
+ };
17
+
13
18
  var attributeName;
14
19
  var attributeNameLowerCased;
15
20
  var attributeValue;
16
21
  var propName;
17
22
  var propertyInfo;
18
23
  var props = {};
24
+ var inputIsValueOnly = attributes.type && valueOnlyInputs[attributes.type];
19
25
 
20
26
  for (attributeName in attributes) {
21
27
  attributeValue = attributes[attributeName];
@@ -28,11 +34,22 @@ module.exports = function attributesToProps(attributes) {
28
34
 
29
35
  // convert HTML/SVG attribute to React prop
30
36
  attributeNameLowerCased = attributeName.toLowerCase();
31
- propName = reactProperty.possibleStandardNames[attributeNameLowerCased];
37
+ propName = getPropName(attributeNameLowerCased);
32
38
 
33
39
  if (propName) {
34
- props[propName] = attributeValue;
35
40
  propertyInfo = reactProperty.getPropertyInfo(propName);
41
+
42
+ // convert attribute to uncontrolled component prop (e.g., `value` to `defaultValue`)
43
+ // https://reactjs.org/docs/uncontrolled-components.html
44
+ if (
45
+ (propName === 'checked' || propName === 'value') &&
46
+ !inputIsValueOnly
47
+ ) {
48
+ propName = getPropName('default' + attributeNameLowerCased);
49
+ }
50
+
51
+ props[propName] = attributeValue;
52
+
36
53
  switch (propertyInfo && propertyInfo.type) {
37
54
  case reactProperty.BOOLEAN:
38
55
  props[propName] = true;
@@ -57,3 +74,13 @@ module.exports = function attributesToProps(attributes) {
57
74
 
58
75
  return props;
59
76
  };
77
+
78
+ /**
79
+ * Gets prop name from lowercased attribute name.
80
+ *
81
+ * @param {string} attributeName - Lowercased attribute name.
82
+ * @return {string}
83
+ */
84
+ function getPropName(attributeName) {
85
+ return reactProperty.possibleStandardNames[attributeName];
86
+ }
@@ -3,6 +3,7 @@ var attributesToProps = require('./attributes-to-props');
3
3
  var utilities = require('./utilities');
4
4
 
5
5
  var setStyleProp = utilities.setStyleProp;
6
+ var canTextBeChildOfNode = utilities.canTextBeChildOfNode;
6
7
 
7
8
  /**
8
9
  * Converts DOM nodes to JSX element(s).
@@ -23,11 +24,11 @@ function domToReact(nodes, options) {
23
24
 
24
25
  var result = [];
25
26
  var node;
27
+ var isWhitespace;
26
28
  var hasReplace = typeof options.replace === 'function';
27
29
  var replaceElement;
28
30
  var props;
29
31
  var children;
30
- var data;
31
32
  var trim = options.trim;
32
33
 
33
34
  for (var i = 0, len = nodes.length; i < len; i++) {
@@ -51,15 +52,23 @@ function domToReact(nodes, options) {
51
52
  }
52
53
 
53
54
  if (node.type === 'text') {
54
- // if trim option is enabled, skip whitespace text nodes
55
- if (trim) {
56
- data = node.data.trim();
57
- if (data) {
58
- result.push(node.data);
59
- }
60
- } else {
61
- result.push(node.data);
55
+ isWhitespace = !node.data.trim().length;
56
+
57
+ if (isWhitespace && node.parent && !canTextBeChildOfNode(node.parent)) {
58
+ // We have a whitespace node that can't be nested in its parent
59
+ // so skip it
60
+ continue;
62
61
  }
62
+
63
+ if (trim && isWhitespace) {
64
+ // Trim is enabled and we have a whitespace node
65
+ // so skip it
66
+ continue;
67
+ }
68
+
69
+ // We have a text node that's not whitespace and it can be nested
70
+ // in its parent so add it to the results
71
+ result.push(node.data);
63
72
  continue;
64
73
  }
65
74
 
package/lib/utilities.js CHANGED
@@ -96,9 +96,35 @@ function setStyleProp(style, props) {
96
96
  */
97
97
  var PRESERVE_CUSTOM_ATTRIBUTES = React.version.split('.')[0] >= 16;
98
98
 
99
+ // Taken from
100
+ // https://github.com/facebook/react/blob/cae635054e17a6f107a39d328649137b83f25972/packages/react-dom/src/client/validateDOMNesting.js#L213
101
+ var elementsWithNoTextChildren = new Set([
102
+ 'tr',
103
+ 'tbody',
104
+ 'thead',
105
+ 'tfoot',
106
+ 'colgroup',
107
+ 'table',
108
+ 'head',
109
+ 'html',
110
+ 'frameset'
111
+ ]);
112
+
113
+ /**
114
+ * Checks if the given node can contain text nodes
115
+ *
116
+ * @param {DomElement} node
117
+ * @returns {boolean}
118
+ */
119
+ function canTextBeChildOfNode(node) {
120
+ return !elementsWithNoTextChildren.has(node.name);
121
+ }
122
+
99
123
  module.exports = {
100
124
  PRESERVE_CUSTOM_ATTRIBUTES: PRESERVE_CUSTOM_ATTRIBUTES,
101
125
  invertObject: invertObject,
102
126
  isCustomComponent: isCustomComponent,
103
- setStyleProp: setStyleProp
127
+ setStyleProp: setStyleProp,
128
+ canTextBeChildOfNode: canTextBeChildOfNode,
129
+ elementsWithNoTextChildren: elementsWithNoTextChildren
104
130
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "html-react-parser",
3
- "version": "1.4.1",
3
+ "version": "1.4.5",
4
4
  "description": "HTML to React parser.",
5
5
  "author": "Mark <mark@remarkablemark.org>",
6
6
  "main": "index.js",
@@ -37,36 +37,36 @@
37
37
  "dom"
38
38
  ],
39
39
  "dependencies": {
40
- "domhandler": "4.2.2",
41
- "html-dom-parser": "1.0.3",
40
+ "domhandler": "4.3.0",
41
+ "html-dom-parser": "1.0.4",
42
42
  "react-property": "2.0.0",
43
43
  "style-to-js": "1.1.0"
44
44
  },
45
45
  "devDependencies": {
46
- "@commitlint/cli": "15.0.0",
47
- "@commitlint/config-conventional": "15.0.0",
46
+ "@commitlint/cli": "16.0.1",
47
+ "@commitlint/config-conventional": "16.0.0",
48
48
  "@rollup/plugin-commonjs": "21.0.1",
49
- "@rollup/plugin-node-resolve": "13.0.6",
50
- "@size-limit/preset-big-lib": "5.0.3",
51
- "@types/react": "17.0.37",
52
- "@typescript-eslint/parser": "5.4.0",
49
+ "@rollup/plugin-node-resolve": "13.1.2",
50
+ "@size-limit/preset-big-lib": "7.0.4",
51
+ "@types/react": "17.0.38",
52
+ "@typescript-eslint/parser": "5.9.0",
53
53
  "benchmark": "2.1.4",
54
54
  "dtslint": "4.2.1",
55
- "eslint": "8.3.0",
55
+ "eslint": "8.6.0",
56
56
  "eslint-plugin-prettier": "4.0.0",
57
57
  "husky": "7.0.4",
58
- "jest": "27.3.1",
59
- "lint-staged": "12.1.2",
58
+ "jest": "27.4.5",
59
+ "lint-staged": "12.1.5",
60
60
  "pinst": "2.1.6",
61
- "preact": "10.6.1",
62
- "prettier": "2.5.0",
61
+ "preact": "10.6.4",
62
+ "prettier": "2.5.1",
63
63
  "react": "17.0.2",
64
64
  "react-dom": "17.0.2",
65
65
  "rimraf": "3.0.2",
66
- "rollup": "2.60.1",
66
+ "rollup": "2.62.0",
67
67
  "rollup-plugin-terser": "7.0.2",
68
- "size-limit": "5.0.3",
69
- "typescript": "4.5.2"
68
+ "size-limit": "7.0.4",
69
+ "typescript": "4.5.4"
70
70
  },
71
71
  "peerDependencies": {
72
72
  "react": "0.14 || 15 || 16 || 17"