html-react-parser 0.14.2 → 0.14.3
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.
- package/CHANGELOG.md +9 -0
- package/README.md +55 -24
- package/dist/html-react-parser.js +50 -50
- package/dist/html-react-parser.js.map +1 -1
- package/dist/html-react-parser.min.js +1 -1
- package/dist/html-react-parser.min.js.map +1 -1
- package/lib/attributes-to-props.js +6 -9
- package/lib/dom-to-react.js +21 -15
- package/lib/utilities.js +19 -2
- package/package.json +20 -20
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [0.14.3](https://github.com/remarkablemark/html-react-parser/compare/v0.14.2...v0.14.3) (2020-12-12)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **dom-to-react:** transform style to object for Web Components ([83efbce](https://github.com/remarkablemark/html-react-parser/commit/83efbce1123d3fb6d28b066cf60559a769e9a138)), closes [#188](https://github.com/remarkablemark/html-react-parser/issues/188)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
5
14
|
<a name="0.14.2"></a>
|
|
6
15
|
## [0.14.2](https://github.com/remarkablemark/html-react-parser/compare/v0.14.1...v0.14.2) (2020-11-23)
|
|
7
16
|
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://nodei.co/npm/html-react-parser/)
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/html-react-parser)
|
|
6
|
-
[](https://github.com/remarkablemark/html-react-parser/actions?query=workflow%3Abuild)
|
|
7
7
|
[](https://coveralls.io/github/remarkablemark/html-react-parser?branch=master)
|
|
8
8
|
[](https://david-dm.org/remarkablemark/html-react-parser)
|
|
9
9
|
[](https://www.npmjs.com/package/html-react-parser)
|
|
@@ -17,16 +17,47 @@ HTMLReactParser(string[, options])
|
|
|
17
17
|
|
|
18
18
|
It converts an HTML string to one or more [React elements](https://reactjs.org/docs/react-api.html#creating-react-elements). There's also an option to [replace an element](#replacedomnode) with your own.
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Example:
|
|
21
21
|
|
|
22
22
|
```js
|
|
23
|
-
|
|
23
|
+
const parse = require('html-react-parser');
|
|
24
24
|
parse('<div>text</div>'); // equivalent to `React.createElement('div', {}, 'text')`
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
[CodeSandbox](https://codesandbox.io/s/940pov1l4w) | [
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
[CodeSandbox](https://codesandbox.io/s/940pov1l4w) | [Repl.it](https://repl.it/@remarkablemark/html-react-parser) | [JSFiddle](https://jsfiddle.net/remarkablemark/7v86d800/) | [Examples](https://github.com/remarkablemark/html-react-parser/tree/master/examples)
|
|
28
|
+
|
|
29
|
+
<details>
|
|
30
|
+
<summary>Table of Contents</summary>
|
|
31
|
+
|
|
32
|
+
- [Install](#install)
|
|
33
|
+
- [Usage](#usage)
|
|
34
|
+
- [Options](#options)
|
|
35
|
+
- [replace(domNode)](#replacedomnode)
|
|
36
|
+
- [library](#library)
|
|
37
|
+
- [htmlparser2](#htmlparser2)
|
|
38
|
+
- [trim](#trim)
|
|
39
|
+
- [FAQ](#faq)
|
|
40
|
+
- [Is this XSS safe?](#is-this-xss-safe)
|
|
41
|
+
- [Does invalid HTML get sanitized?](#does-invalid-html-get-sanitized)
|
|
42
|
+
- [Are `<script>` tags parsed?](#are-script-tags-parsed)
|
|
43
|
+
- [Attributes aren't getting called](#attributes-arent-getting-called)
|
|
44
|
+
- [Parser throws an error](#parser-throws-an-error)
|
|
45
|
+
- [Is SSR supported?](#is-ssr-supported)
|
|
46
|
+
- [Elements aren't nested correctly](#elements-arent-nested-correctly)
|
|
47
|
+
- [Warning: validateDOMNesting(...): Whitespace text nodes cannot appear as a child of table](#warning-validatedomnesting-whitespace-text-nodes-cannot-appear-as-a-child-of-table)
|
|
48
|
+
- [Don't change case of tags](#dont-change-case-of-tags)
|
|
49
|
+
- [Benchmarks](#benchmarks)
|
|
50
|
+
- [Contributors](#contributors)
|
|
51
|
+
- [Code Contributors](#code-contributors)
|
|
52
|
+
- [Financial Contributors](#financial-contributors)
|
|
53
|
+
- [Individuals](#individuals)
|
|
54
|
+
- [Organizations](#organizations)
|
|
55
|
+
- [Support](#support)
|
|
56
|
+
- [License](#license)
|
|
57
|
+
|
|
58
|
+
</details>
|
|
59
|
+
|
|
60
|
+
## Install
|
|
30
61
|
|
|
31
62
|
[NPM](https://www.npmjs.com/package/html-react-parser):
|
|
32
63
|
|
|
@@ -53,7 +84,7 @@ $ yarn add html-react-parser
|
|
|
53
84
|
|
|
54
85
|
## Usage
|
|
55
86
|
|
|
56
|
-
Import the module:
|
|
87
|
+
Import or require the module:
|
|
57
88
|
|
|
58
89
|
```js
|
|
59
90
|
// ES Modules
|
|
@@ -296,33 +327,33 @@ parse('<p> </p>', { trim: true }); // React.createElement('p')
|
|
|
296
327
|
|
|
297
328
|
## FAQ
|
|
298
329
|
|
|
299
|
-
#### Is this
|
|
330
|
+
#### Is this XSS safe?
|
|
300
331
|
|
|
301
332
|
No, this library is _**not**_ [XSS (cross-site scripting)](https://wikipedia.org/wiki/Cross-site_scripting) safe. See [#94](https://github.com/remarkablemark/html-react-parser/issues/94).
|
|
302
333
|
|
|
303
|
-
#### Does
|
|
334
|
+
#### Does invalid HTML get sanitized?
|
|
304
335
|
|
|
305
|
-
No, this library does _**not**_
|
|
336
|
+
No, this library does _**not**_ sanitize HTML. See [#124](https://github.com/remarkablemark/html-react-parser/issues/124), [#125](https://github.com/remarkablemark/html-react-parser/issues/125), and [#141](https://github.com/remarkablemark/html-react-parser/issues/141).
|
|
306
337
|
|
|
307
338
|
#### Are `<script>` tags parsed?
|
|
308
339
|
|
|
309
340
|
Although `<script>` tags and their contents are rendered on the server-side, they're not evaluated on the client-side. See [#98](https://github.com/remarkablemark/html-react-parser/issues/98).
|
|
310
341
|
|
|
311
|
-
####
|
|
342
|
+
#### Attributes aren't getting called
|
|
312
343
|
|
|
313
|
-
|
|
344
|
+
The reason why your HTML attributes aren't getting called is because [inline event handlers](https://developer.mozilla.org/docs/Web/Guide/Events/Event_handlers) (e.g., `onclick`) are parsed as a _string_ rather than a _function_. See [#73](https://github.com/remarkablemark/html-react-parser/issues/73).
|
|
314
345
|
|
|
315
|
-
####
|
|
346
|
+
#### Parser throws an error
|
|
316
347
|
|
|
317
|
-
|
|
348
|
+
If the parser throws an erorr, check if your arguments are valid. See ["Does invalid HTML get sanitized?"](#does-invalid-html-get-sanitized).
|
|
318
349
|
|
|
319
|
-
####
|
|
350
|
+
#### Is SSR supported?
|
|
320
351
|
|
|
321
|
-
Yes,
|
|
352
|
+
Yes, server-side rendering on Node.js is supported by this library. See [demo](https://repl.it/@remarkablemark/html-react-parser-SSR).
|
|
322
353
|
|
|
323
|
-
####
|
|
354
|
+
#### Elements aren't nested correctly
|
|
324
355
|
|
|
325
|
-
|
|
356
|
+
If your elements are nested incorrectly, check to make sure your [HTML markup is valid](https://validator.w3.org/). The HTML to DOM parsing will be affected if you're using self-closing syntax (`/>`) on non-void elements:
|
|
326
357
|
|
|
327
358
|
```js
|
|
328
359
|
parse('<div /><div />'); // returns single element instead of array of elements
|
|
@@ -330,13 +361,13 @@ parse('<div /><div />'); // returns single element instead of array of elements
|
|
|
330
361
|
|
|
331
362
|
See [#158](https://github.com/remarkablemark/html-react-parser/issues/158).
|
|
332
363
|
|
|
333
|
-
####
|
|
364
|
+
#### Warning: validateDOMNesting(...): Whitespace text nodes cannot appear as a child of table
|
|
334
365
|
|
|
335
|
-
Enable the [trim](
|
|
366
|
+
Enable the [trim](#trim) option. See [#155](https://github.com/remarkablemark/html-react-parser/issues/155).
|
|
336
367
|
|
|
337
|
-
#### Don't change case of tags
|
|
368
|
+
#### Don't change case of tags
|
|
338
369
|
|
|
339
|
-
Tags are lowercased by default. To prevent that from happening, pass the [htmlparser2 option](
|
|
370
|
+
Tags are lowercased by default. To prevent that from happening, pass the [htmlparser2 option](#htmlparser2):
|
|
340
371
|
|
|
341
372
|
```js
|
|
342
373
|
const options = {
|
|
@@ -403,10 +434,10 @@ Support this project with your organization. Your logo will show up here with a
|
|
|
403
434
|
## Support
|
|
404
435
|
|
|
405
436
|
- [GitHub Sponsors](https://b.remarkabl.org/github-sponsors)
|
|
406
|
-
- [Patreon](https://b.remarkabl.org/patreon)
|
|
407
437
|
- [Open Collective](https://b.remarkabl.org/open-collective-html-react-parser)
|
|
408
|
-
- [Ko-fi](https://b.remarkabl.org/ko-fi)
|
|
409
438
|
- [Tidelift](https://b.remarkabl.org/tidelift-html-react-parser)
|
|
439
|
+
- [Patreon](https://b.remarkabl.org/patreon)
|
|
440
|
+
- [Ko-fi](https://b.remarkabl.org/ko-fi)
|
|
410
441
|
- [Liberapay](https://b.remarkabl.org/liberapay)
|
|
411
442
|
- [Teepsring](https://b.remarkabl.org/teespring)
|
|
412
443
|
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('react')) :
|
|
3
3
|
typeof define === 'function' && define.amd ? define(['react'], factory) :
|
|
4
4
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.HTMLReactParser = factory(global.React));
|
|
5
|
-
}(this, (function (
|
|
5
|
+
}(this, (function (React) { 'use strict';
|
|
6
6
|
|
|
7
7
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
8
8
|
|
|
9
|
-
var
|
|
9
|
+
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
10
10
|
|
|
11
11
|
var HTMLDOMPropertyConfig = {
|
|
12
12
|
Properties: {
|
|
@@ -608,22 +608,9 @@
|
|
|
608
608
|
|
|
609
609
|
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
610
610
|
|
|
611
|
-
function
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
function createCommonjsModule(fn, basedir, module) {
|
|
616
|
-
return module = {
|
|
617
|
-
path: basedir,
|
|
618
|
-
exports: {},
|
|
619
|
-
require: function (path, base) {
|
|
620
|
-
return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
|
|
621
|
-
}
|
|
622
|
-
}, fn(module, module.exports), module.exports;
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
function commonjsRequire () {
|
|
626
|
-
throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
|
|
611
|
+
function createCommonjsModule(fn) {
|
|
612
|
+
var module = { exports: {} };
|
|
613
|
+
return fn(module, module.exports), module.exports;
|
|
627
614
|
}
|
|
628
615
|
|
|
629
616
|
// http://www.w3.org/TR/CSS21/grammar.html
|
|
@@ -955,9 +942,6 @@
|
|
|
955
942
|
exports.camelCase = camelCase;
|
|
956
943
|
});
|
|
957
944
|
|
|
958
|
-
unwrapExports(utilities);
|
|
959
|
-
var utilities_1 = utilities.camelCase;
|
|
960
|
-
|
|
961
945
|
var cjs = createCommonjsModule(function (module, exports) {
|
|
962
946
|
var __importDefault = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) {
|
|
963
947
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
@@ -980,7 +964,7 @@
|
|
|
980
964
|
exports["default"] = StyleToJS;
|
|
981
965
|
});
|
|
982
966
|
|
|
983
|
-
|
|
967
|
+
var styleToJS = cjs.default;
|
|
984
968
|
|
|
985
969
|
/**
|
|
986
970
|
* Swap key with value in an object.
|
|
@@ -1052,20 +1036,35 @@
|
|
|
1052
1036
|
}
|
|
1053
1037
|
}
|
|
1054
1038
|
|
|
1039
|
+
var styleToJSOptions = { reactCompat: true };
|
|
1040
|
+
|
|
1055
1041
|
/**
|
|
1056
|
-
*
|
|
1042
|
+
* Sets style prop.
|
|
1043
|
+
*
|
|
1044
|
+
* @param {null|undefined|string} style
|
|
1045
|
+
* @param {object} props
|
|
1046
|
+
*/
|
|
1047
|
+
function setStyleProp(style, props) {
|
|
1048
|
+
if (style === null || style === undefined) {
|
|
1049
|
+
return;
|
|
1050
|
+
}
|
|
1051
|
+
props.style = styleToJS(style, styleToJSOptions);
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
/**
|
|
1055
|
+
* @constant {boolean}
|
|
1057
1056
|
* @see {@link https://reactjs.org/blog/2017/09/08/dom-attributes-in-react-16.html}
|
|
1058
1057
|
*/
|
|
1059
|
-
var PRESERVE_CUSTOM_ATTRIBUTES =
|
|
1058
|
+
var PRESERVE_CUSTOM_ATTRIBUTES = React__default['default'].version.split('.')[0] >= 16;
|
|
1060
1059
|
|
|
1061
1060
|
var utilities$1 = {
|
|
1062
1061
|
PRESERVE_CUSTOM_ATTRIBUTES: PRESERVE_CUSTOM_ATTRIBUTES,
|
|
1063
1062
|
invertObject: invertObject,
|
|
1064
|
-
isCustomComponent: isCustomComponent
|
|
1063
|
+
isCustomComponent: isCustomComponent,
|
|
1064
|
+
setStyleProp: setStyleProp
|
|
1065
1065
|
};
|
|
1066
1066
|
|
|
1067
|
-
var
|
|
1068
|
-
|
|
1067
|
+
var setStyleProp$1 = utilities$1.setStyleProp;
|
|
1069
1068
|
|
|
1070
1069
|
var htmlProperties = reactProperty.html;
|
|
1071
1070
|
var svgProperties = reactProperty.svg;
|
|
@@ -1073,13 +1072,11 @@
|
|
|
1073
1072
|
|
|
1074
1073
|
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
1075
1074
|
|
|
1076
|
-
var styleToJSOptions = { reactCompat: true };
|
|
1077
|
-
|
|
1078
1075
|
/**
|
|
1079
1076
|
* Converts HTML/SVG DOM attributes to React props.
|
|
1080
1077
|
*
|
|
1081
|
-
* @param {
|
|
1082
|
-
* @return {
|
|
1078
|
+
* @param {object} [attributes={}] - HTML/SVG DOM attributes.
|
|
1079
|
+
* @return {object} - React props.
|
|
1083
1080
|
*/
|
|
1084
1081
|
function attributesToProps(attributes) {
|
|
1085
1082
|
attributes = attributes || {};
|
|
@@ -1124,32 +1121,32 @@
|
|
|
1124
1121
|
}
|
|
1125
1122
|
}
|
|
1126
1123
|
|
|
1127
|
-
//
|
|
1128
|
-
|
|
1129
|
-
props.style = styleToJS(attributes.style, styleToJSOptions);
|
|
1130
|
-
}
|
|
1124
|
+
// transform inline style to object
|
|
1125
|
+
setStyleProp$1(attributes.style, props);
|
|
1131
1126
|
|
|
1132
1127
|
return props;
|
|
1133
1128
|
}
|
|
1134
1129
|
|
|
1135
1130
|
var attributesToProps_1 = attributesToProps;
|
|
1136
1131
|
|
|
1132
|
+
var setStyleProp$2 = utilities$1.setStyleProp;
|
|
1133
|
+
|
|
1137
1134
|
/**
|
|
1138
1135
|
* Converts DOM nodes to React elements.
|
|
1139
1136
|
*
|
|
1140
|
-
* @param
|
|
1141
|
-
* @param
|
|
1142
|
-
* @param
|
|
1143
|
-
* @param
|
|
1144
|
-
* @return {
|
|
1137
|
+
* @param {DomElement[]} nodes - DOM nodes.
|
|
1138
|
+
* @param {object} [options={}] - Options.
|
|
1139
|
+
* @param {Function} [options.replace] - Replacer.
|
|
1140
|
+
* @param {object} [options.library] - Library (React/Preact/etc.).
|
|
1141
|
+
* @return {string|ReactElement|ReactElement[]}
|
|
1145
1142
|
*/
|
|
1146
1143
|
function domToReact(nodes, options) {
|
|
1147
1144
|
options = options || {};
|
|
1148
1145
|
|
|
1149
|
-
var
|
|
1150
|
-
var cloneElement =
|
|
1151
|
-
var createElement =
|
|
1152
|
-
var isValidElement =
|
|
1146
|
+
var library = options.library || React__default['default'];
|
|
1147
|
+
var cloneElement = library.cloneElement;
|
|
1148
|
+
var createElement = library.createElement;
|
|
1149
|
+
var isValidElement = library.isValidElement;
|
|
1153
1150
|
|
|
1154
1151
|
var result = [];
|
|
1155
1152
|
var node;
|
|
@@ -1194,8 +1191,10 @@
|
|
|
1194
1191
|
}
|
|
1195
1192
|
|
|
1196
1193
|
props = node.attribs;
|
|
1197
|
-
if (
|
|
1198
|
-
props
|
|
1194
|
+
if (skipAttributesToProps(node)) {
|
|
1195
|
+
setStyleProp$2(props.style, props);
|
|
1196
|
+
} else if (props) {
|
|
1197
|
+
props = attributesToProps_1(props);
|
|
1199
1198
|
}
|
|
1200
1199
|
|
|
1201
1200
|
children = null;
|
|
@@ -1241,12 +1240,13 @@
|
|
|
1241
1240
|
}
|
|
1242
1241
|
|
|
1243
1242
|
/**
|
|
1244
|
-
* Determines whether attributes should be
|
|
1243
|
+
* Determines whether DOM element attributes should be transformed to props.
|
|
1244
|
+
* Web Components should not have their attributes transformed except for `style`.
|
|
1245
1245
|
*
|
|
1246
|
-
* @param
|
|
1247
|
-
* @return {
|
|
1246
|
+
* @param {DomElement} node
|
|
1247
|
+
* @return {boolean}
|
|
1248
1248
|
*/
|
|
1249
|
-
function
|
|
1249
|
+
function skipAttributesToProps(node) {
|
|
1250
1250
|
return (
|
|
1251
1251
|
utilities$1.PRESERVE_CUSTOM_ATTRIBUTES &&
|
|
1252
1252
|
node.type === 'tag' &&
|