html-react-parser 4.2.0 → 4.2.2
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/README.md +30 -10
- package/dist/html-react-parser.js +53 -49
- 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/utilities.js +33 -27
- package/package.json +15 -15
package/README.md
CHANGED
|
@@ -155,13 +155,15 @@ The `replace` callback's first argument is [domhandler](https://github.com/fb55/
|
|
|
155
155
|
|
|
156
156
|
```js
|
|
157
157
|
parse('<br>', {
|
|
158
|
-
replace: domNode => {
|
|
158
|
+
replace: (domNode) => {
|
|
159
159
|
console.dir(domNode, { depth: null });
|
|
160
160
|
}
|
|
161
161
|
});
|
|
162
162
|
```
|
|
163
163
|
|
|
164
|
-
|
|
164
|
+
<details>
|
|
165
|
+
<summary>Console output</summary>
|
|
166
|
+
<p>
|
|
165
167
|
|
|
166
168
|
```js
|
|
167
169
|
Element {
|
|
@@ -177,11 +179,14 @@ Element {
|
|
|
177
179
|
}
|
|
178
180
|
```
|
|
179
181
|
|
|
182
|
+
</p>
|
|
183
|
+
</details>
|
|
184
|
+
|
|
180
185
|
The element is replaced if a **valid** React element is returned:
|
|
181
186
|
|
|
182
187
|
```jsx
|
|
183
188
|
parse('<p id="replace">text</p>', {
|
|
184
|
-
replace: domNode => {
|
|
189
|
+
replace: (domNode) => {
|
|
185
190
|
if (domNode.attribs && domNode.attribs.id === 'replace') {
|
|
186
191
|
return <span>replaced</span>;
|
|
187
192
|
}
|
|
@@ -197,7 +202,7 @@ For TypeScript projects, you may need to check that `domNode` is an instance of
|
|
|
197
202
|
import { HTMLReactParserOptions, Element } from 'html-react-parser';
|
|
198
203
|
|
|
199
204
|
const options: HTMLReactParserOptions = {
|
|
200
|
-
replace: domNode => {
|
|
205
|
+
replace: (domNode) => {
|
|
201
206
|
if (domNode instanceof Element && domNode.attribs) {
|
|
202
207
|
// ...
|
|
203
208
|
}
|
|
@@ -245,7 +250,9 @@ const options = {
|
|
|
245
250
|
parse(html, options);
|
|
246
251
|
```
|
|
247
252
|
|
|
248
|
-
|
|
253
|
+
<details>
|
|
254
|
+
<summary>HTML output</summary>
|
|
255
|
+
<p>
|
|
249
256
|
|
|
250
257
|
<!-- prettier-ignore-start -->
|
|
251
258
|
|
|
@@ -259,6 +266,9 @@ HTML output:
|
|
|
259
266
|
|
|
260
267
|
<!-- prettier-ignore-end -->
|
|
261
268
|
|
|
269
|
+
</p>
|
|
270
|
+
</details>
|
|
271
|
+
|
|
262
272
|
#### replace element attributes
|
|
263
273
|
|
|
264
274
|
Convert DOM attributes to React props with `attributesToProps`:
|
|
@@ -271,7 +281,7 @@ const html = `
|
|
|
271
281
|
`;
|
|
272
282
|
|
|
273
283
|
const options = {
|
|
274
|
-
replace: domNode => {
|
|
284
|
+
replace: (domNode) => {
|
|
275
285
|
if (domNode.attribs && domNode.name === 'main') {
|
|
276
286
|
const props = attributesToProps(domNode.attribs);
|
|
277
287
|
return <div {...props} />;
|
|
@@ -282,12 +292,17 @@ const options = {
|
|
|
282
292
|
parse(html, options);
|
|
283
293
|
```
|
|
284
294
|
|
|
285
|
-
|
|
295
|
+
<details>
|
|
296
|
+
<summary>HTML output</summary>
|
|
297
|
+
<p>
|
|
286
298
|
|
|
287
299
|
```html
|
|
288
300
|
<div class="prettify" style="background:#fff;text-align:center"></div>
|
|
289
301
|
```
|
|
290
302
|
|
|
303
|
+
</p>
|
|
304
|
+
</details>
|
|
305
|
+
|
|
291
306
|
#### replace and remove element
|
|
292
307
|
|
|
293
308
|
[Exclude](https://replit.com/@remarkablemark/html-react-parser-56) an element from rendering by replacing it with `<React.Fragment>`:
|
|
@@ -298,12 +313,17 @@ parse('<p><br id="remove"></p>', {
|
|
|
298
313
|
});
|
|
299
314
|
```
|
|
300
315
|
|
|
301
|
-
|
|
316
|
+
<details>
|
|
317
|
+
<summary>HTML output</summary>
|
|
318
|
+
<p>
|
|
302
319
|
|
|
303
320
|
```html
|
|
304
321
|
<p></p>
|
|
305
322
|
```
|
|
306
323
|
|
|
324
|
+
</p>
|
|
325
|
+
</details>
|
|
326
|
+
|
|
307
327
|
### transform
|
|
308
328
|
|
|
309
329
|
The `transform` option allows you to transform each element individually after it's parsed.
|
|
@@ -417,7 +437,7 @@ For the `replace` option, you may need to do the following:
|
|
|
417
437
|
import { Element } from 'domhandler/lib/node';
|
|
418
438
|
|
|
419
439
|
parse('<br class="remove">', {
|
|
420
|
-
replace: domNode => {
|
|
440
|
+
replace: (domNode) => {
|
|
421
441
|
if (domNode instanceof Element && domNode.attribs.class === 'remove') {
|
|
422
442
|
return <></>;
|
|
423
443
|
}
|
|
@@ -522,7 +542,7 @@ If you see the TypeScript error:
|
|
|
522
542
|
node_modules/htmlparser2/lib/index.d.ts:2:23 - error TS1005: ',' expected.
|
|
523
543
|
|
|
524
544
|
2 export { Parser, type ParserOptions };
|
|
525
|
-
|
|
545
|
+
~~~~~~~~~~~~~
|
|
526
546
|
```
|
|
527
547
|
|
|
528
548
|
Then upgrade to the latest version of [typescript](https://www.npmjs.com/package/typescript). See [#748](https://github.com/remarkablemark/html-react-parser/issues/748).
|
|
@@ -2222,7 +2222,7 @@
|
|
|
2222
2222
|
|
|
2223
2223
|
var utilities$3 = {};
|
|
2224
2224
|
|
|
2225
|
-
utilities$3
|
|
2225
|
+
Object.defineProperty(utilities$3, "__esModule", { value: true });
|
|
2226
2226
|
utilities$3.camelCase = void 0;
|
|
2227
2227
|
var CUSTOM_PROPERTY_REGEX = /^--[a-zA-Z0-9-]+$/;
|
|
2228
2228
|
var HYPHEN_REGEX = /-([a-z])/g;
|
|
@@ -2254,27 +2254,25 @@
|
|
|
2254
2254
|
};
|
|
2255
2255
|
utilities$3.camelCase = camelCase;
|
|
2256
2256
|
|
|
2257
|
-
(function (
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
exports["default"] = StyleToJS;
|
|
2277
|
-
} (cjs));
|
|
2257
|
+
var __importDefault = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) {
|
|
2258
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
2259
|
+
};
|
|
2260
|
+
Object.defineProperty(cjs, "__esModule", { value: true });
|
|
2261
|
+
var style_to_object_1 = __importDefault(styleToObjectExports);
|
|
2262
|
+
var utilities_1 = utilities$3;
|
|
2263
|
+
function StyleToJS(style, options) {
|
|
2264
|
+
var output = {};
|
|
2265
|
+
if (!style || typeof style !== 'string') {
|
|
2266
|
+
return output;
|
|
2267
|
+
}
|
|
2268
|
+
(0, style_to_object_1.default)(style, function (property, value) {
|
|
2269
|
+
if (property && value) {
|
|
2270
|
+
output[(0, utilities_1.camelCase)(property, options)] = value;
|
|
2271
|
+
}
|
|
2272
|
+
});
|
|
2273
|
+
return output;
|
|
2274
|
+
}
|
|
2275
|
+
cjs.default = StyleToJS;
|
|
2278
2276
|
|
|
2279
2277
|
var React$1 = require$$0__default["default"];
|
|
2280
2278
|
var styleToJS = cjs.default;
|
|
@@ -2291,14 +2289,12 @@
|
|
|
2291
2289
|
throw new TypeError('First argument must be an object');
|
|
2292
2290
|
}
|
|
2293
2291
|
|
|
2294
|
-
var key;
|
|
2295
|
-
var value;
|
|
2296
2292
|
var isOverridePresent = typeof override === 'function';
|
|
2297
2293
|
var overrides = {};
|
|
2298
2294
|
var result = {};
|
|
2299
2295
|
|
|
2300
|
-
for (key in obj) {
|
|
2301
|
-
value = obj[key];
|
|
2296
|
+
for (var key in obj) {
|
|
2297
|
+
var value = obj[key];
|
|
2302
2298
|
|
|
2303
2299
|
if (isOverridePresent) {
|
|
2304
2300
|
overrides = override(key, value);
|
|
@@ -2316,6 +2312,17 @@
|
|
|
2316
2312
|
return result;
|
|
2317
2313
|
}
|
|
2318
2314
|
|
|
2315
|
+
var RESERVED_SVG_MATHML_ELEMENTS = new Set([
|
|
2316
|
+
'annotation-xml',
|
|
2317
|
+
'color-profile',
|
|
2318
|
+
'font-face',
|
|
2319
|
+
'font-face-src',
|
|
2320
|
+
'font-face-uri',
|
|
2321
|
+
'font-face-format',
|
|
2322
|
+
'font-face-name',
|
|
2323
|
+
'missing-glyph'
|
|
2324
|
+
]);
|
|
2325
|
+
|
|
2319
2326
|
/**
|
|
2320
2327
|
* Check if a given tag is a custom component.
|
|
2321
2328
|
*
|
|
@@ -2323,33 +2330,24 @@
|
|
|
2323
2330
|
*
|
|
2324
2331
|
* @param {string} tagName - The name of the html tag.
|
|
2325
2332
|
* @param {object} props - The props being passed to the element.
|
|
2326
|
-
* @returns - Whether tag is custom component.
|
|
2333
|
+
* @returns {boolean} - Whether tag is custom component.
|
|
2327
2334
|
*/
|
|
2328
2335
|
function isCustomComponent(tagName, props) {
|
|
2329
2336
|
if (tagName.indexOf('-') === -1) {
|
|
2330
2337
|
return props && typeof props.is === 'string';
|
|
2331
2338
|
}
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
case 'annotation-xml':
|
|
2339
|
-
case 'color-profile':
|
|
2340
|
-
case 'font-face':
|
|
2341
|
-
case 'font-face-src':
|
|
2342
|
-
case 'font-face-uri':
|
|
2343
|
-
case 'font-face-format':
|
|
2344
|
-
case 'font-face-name':
|
|
2345
|
-
case 'missing-glyph':
|
|
2346
|
-
return false;
|
|
2347
|
-
default:
|
|
2348
|
-
return true;
|
|
2339
|
+
// These are reserved SVG and MathML elements.
|
|
2340
|
+
// We don't mind this whitelist too much because we expect it to never grow.
|
|
2341
|
+
// The alternative is to track the namespace in a few places which is convoluted.
|
|
2342
|
+
// https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
|
|
2343
|
+
if (RESERVED_SVG_MATHML_ELEMENTS.has(tagName)) {
|
|
2344
|
+
return false;
|
|
2349
2345
|
}
|
|
2346
|
+
return true;
|
|
2350
2347
|
}
|
|
2351
2348
|
|
|
2352
|
-
|
|
2349
|
+
// styleToJSOptions
|
|
2350
|
+
var STYLE_TO_JS_OPTIONS = { reactCompat: true };
|
|
2353
2351
|
|
|
2354
2352
|
/**
|
|
2355
2353
|
* Sets style prop.
|
|
@@ -2362,7 +2360,7 @@
|
|
|
2362
2360
|
return;
|
|
2363
2361
|
}
|
|
2364
2362
|
try {
|
|
2365
|
-
props.style = styleToJS(style,
|
|
2363
|
+
props.style = styleToJS(style, STYLE_TO_JS_OPTIONS);
|
|
2366
2364
|
} catch (err) {
|
|
2367
2365
|
props.style = {};
|
|
2368
2366
|
}
|
|
@@ -2376,7 +2374,7 @@
|
|
|
2376
2374
|
|
|
2377
2375
|
// Taken from
|
|
2378
2376
|
// https://github.com/facebook/react/blob/cae635054e17a6f107a39d328649137b83f25972/packages/react-dom/src/client/validateDOMNesting.js#L213
|
|
2379
|
-
var
|
|
2377
|
+
var ELEMENTS_WITH_NO_TEXT_CHILDREN = new Set([
|
|
2380
2378
|
'tr',
|
|
2381
2379
|
'tbody',
|
|
2382
2380
|
'thead',
|
|
@@ -2395,20 +2393,26 @@
|
|
|
2395
2393
|
* @returns - Whether node can contain text nodes.
|
|
2396
2394
|
*/
|
|
2397
2395
|
function canTextBeChildOfNode$1(node) {
|
|
2398
|
-
return !
|
|
2396
|
+
return !ELEMENTS_WITH_NO_TEXT_CHILDREN.has(node.name);
|
|
2399
2397
|
}
|
|
2400
2398
|
|
|
2399
|
+
/**
|
|
2400
|
+
* Returns the first argument as is.
|
|
2401
|
+
*
|
|
2402
|
+
* @param {any} arg - The argument to be returned.
|
|
2403
|
+
* @returns {any} The input argument `arg`.
|
|
2404
|
+
*/
|
|
2401
2405
|
function returnFirstArg(arg) {
|
|
2402
2406
|
return arg;
|
|
2403
2407
|
}
|
|
2404
2408
|
|
|
2405
2409
|
var utilities$2 = {
|
|
2406
2410
|
PRESERVE_CUSTOM_ATTRIBUTES: PRESERVE_CUSTOM_ATTRIBUTES,
|
|
2411
|
+
ELEMENTS_WITH_NO_TEXT_CHILDREN: ELEMENTS_WITH_NO_TEXT_CHILDREN,
|
|
2407
2412
|
invertObject: invertObject,
|
|
2408
2413
|
isCustomComponent: isCustomComponent,
|
|
2409
2414
|
setStyleProp: setStyleProp$1,
|
|
2410
2415
|
canTextBeChildOfNode: canTextBeChildOfNode$1,
|
|
2411
|
-
elementsWithNoTextChildren: elementsWithNoTextChildren,
|
|
2412
2416
|
returnFirstArg: returnFirstArg
|
|
2413
2417
|
};
|
|
2414
2418
|
|