html-react-parser 5.2.15 → 5.2.17
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 +3 -3
- package/dist/html-react-parser.js +73 -32
- 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.d.ts.map +1 -1
- package/lib/attributes-to-props.js +1 -1
- package/lib/attributes-to-props.js.map +1 -1
- package/lib/dom-to-react.d.ts.map +1 -1
- package/lib/dom-to-react.js +9 -5
- package/lib/dom-to-react.js.map +1 -1
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/lib/types.d.ts.map +1 -1
- package/lib/utilities.d.ts +1 -1
- package/lib/utilities.d.ts.map +1 -1
- package/lib/utilities.js +1 -1
- package/lib/utilities.js.map +1 -1
- package/package.json +20 -24
- package/src/attributes-to-props.ts +5 -3
- package/src/dom-to-react.ts +20 -9
- package/src/index.ts +1 -1
- package/src/types.ts +2 -0
- package/src/utilities.ts +1 -1
package/README.md
CHANGED
|
@@ -614,9 +614,9 @@ npm run benchmark
|
|
|
614
614
|
Output of benchmark run on MacBook Pro 2024:
|
|
615
615
|
|
|
616
616
|
```
|
|
617
|
-
html-to-react - Single x 1,
|
|
618
|
-
html-to-react - Multiple x
|
|
619
|
-
html-to-react - Complex x 54,
|
|
617
|
+
html-to-react - Single x 1,270,990 ops/sec ±0.21% (100 runs sampled)
|
|
618
|
+
html-to-react - Multiple x 522,472 ops/sec ±0.64% (94 runs sampled)
|
|
619
|
+
html-to-react - Complex x 54,028 ops/sec ±0.82% (98 runs sampled)
|
|
620
620
|
```
|
|
621
621
|
|
|
622
622
|
Run [Size Limit](https://github.com/ai/size-limit):
|
|
@@ -810,7 +810,7 @@
|
|
|
810
810
|
}, {});
|
|
811
811
|
exports$1.CARRIAGE_RETURN = '\r';
|
|
812
812
|
exports$1.CARRIAGE_RETURN_REGEX = new RegExp(exports$1.CARRIAGE_RETURN, 'g');
|
|
813
|
-
exports$1.CARRIAGE_RETURN_PLACEHOLDER = "__HTML_DOM_PARSER_CARRIAGE_RETURN_PLACEHOLDER_".concat(Date.now(), "__");
|
|
813
|
+
exports$1.CARRIAGE_RETURN_PLACEHOLDER = "__HTML_DOM_PARSER_CARRIAGE_RETURN_PLACEHOLDER_".concat(Date.now().toString(), "__");
|
|
814
814
|
exports$1.CARRIAGE_RETURN_PLACEHOLDER_REGEX = new RegExp(exports$1.CARRIAGE_RETURN_PLACEHOLDER, 'g');
|
|
815
815
|
|
|
816
816
|
} (constants));
|
|
@@ -824,6 +824,7 @@
|
|
|
824
824
|
hasRequiredUtilities$2 = 1;
|
|
825
825
|
Object.defineProperty(utilities$2, "__esModule", { value: true });
|
|
826
826
|
utilities$2.formatAttributes = formatAttributes;
|
|
827
|
+
utilities$2.hasOpenTag = hasOpenTag;
|
|
827
828
|
utilities$2.escapeSpecialCharacters = escapeSpecialCharacters;
|
|
828
829
|
utilities$2.revertEscapedCharacters = revertEscapedCharacters;
|
|
829
830
|
utilities$2.formatDOM = formatDOM;
|
|
@@ -870,6 +871,28 @@
|
|
|
870
871
|
}
|
|
871
872
|
return tagName;
|
|
872
873
|
}
|
|
874
|
+
/**
|
|
875
|
+
* Checks if an HTML string contains an opening tag (case-insensitive).
|
|
876
|
+
*
|
|
877
|
+
* @param html - HTML string.
|
|
878
|
+
* @param tagName - Tag name to search for (e.g., 'head' or 'body').
|
|
879
|
+
* @returns - Whether the tag is found.
|
|
880
|
+
*/
|
|
881
|
+
function hasOpenTag(html, tagName) {
|
|
882
|
+
var openTag = '<' + tagName;
|
|
883
|
+
var index = html.toLowerCase().indexOf(openTag);
|
|
884
|
+
if (index === -1) {
|
|
885
|
+
return false;
|
|
886
|
+
}
|
|
887
|
+
var char = html[index + openTag.length];
|
|
888
|
+
// the character after the tag name must be '>' or whitespace (for attributes)
|
|
889
|
+
return (char === '>' ||
|
|
890
|
+
char === ' ' ||
|
|
891
|
+
char === '\t' ||
|
|
892
|
+
char === '\n' ||
|
|
893
|
+
char === '\r' ||
|
|
894
|
+
char === '/');
|
|
895
|
+
}
|
|
873
896
|
/**
|
|
874
897
|
* Escapes special characters before parsing.
|
|
875
898
|
*
|
|
@@ -897,6 +920,7 @@
|
|
|
897
920
|
* @returns - Nodes.
|
|
898
921
|
*/
|
|
899
922
|
function formatDOM(nodes, parent, directive) {
|
|
923
|
+
var _a, _b, _c, _d;
|
|
900
924
|
if (parent === void 0) { parent = null; }
|
|
901
925
|
var domNodes = [];
|
|
902
926
|
var current;
|
|
@@ -918,16 +942,17 @@
|
|
|
918
942
|
break;
|
|
919
943
|
}
|
|
920
944
|
case 3:
|
|
921
|
-
current = new domhandler_1.Text(revertEscapedCharacters(node.nodeValue));
|
|
945
|
+
current = new domhandler_1.Text(revertEscapedCharacters((_a = node.nodeValue) !== null && _a !== void 0 ? _a : ''));
|
|
922
946
|
break;
|
|
923
947
|
case 8:
|
|
924
|
-
current = new domhandler_1.Comment(node.nodeValue);
|
|
948
|
+
current = new domhandler_1.Comment((_b = node.nodeValue) !== null && _b !== void 0 ? _b : '');
|
|
925
949
|
break;
|
|
926
950
|
default:
|
|
927
951
|
continue;
|
|
928
952
|
}
|
|
929
953
|
// set previous node next
|
|
930
|
-
var prev = domNodes[index - 1]
|
|
954
|
+
var prev = (_c = domNodes[index - 1]) !== null && _c !== void 0 ? _c : null;
|
|
955
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
931
956
|
if (prev) {
|
|
932
957
|
prev.next = current;
|
|
933
958
|
}
|
|
@@ -939,7 +964,7 @@
|
|
|
939
964
|
}
|
|
940
965
|
if (directive) {
|
|
941
966
|
current = new domhandler_1.ProcessingInstruction(directive.substring(0, directive.indexOf(' ')).toLowerCase(), directive);
|
|
942
|
-
current.next = domNodes[0]
|
|
967
|
+
current.next = (_d = domNodes[0]) !== null && _d !== void 0 ? _d : null;
|
|
943
968
|
current.parent = parent;
|
|
944
969
|
domNodes.unshift(current);
|
|
945
970
|
if (domNodes[1]) {
|
|
@@ -965,20 +990,17 @@
|
|
|
965
990
|
var HEAD = 'head';
|
|
966
991
|
var BODY = 'body';
|
|
967
992
|
var FIRST_TAG_REGEX = /<([a-zA-Z]+[0-9]?)/; // e.g., <h1>
|
|
968
|
-
// match-all-characters in case of newlines (DOTALL)
|
|
969
|
-
var HEAD_TAG_REGEX = /<head[^]*>/i;
|
|
970
|
-
var BODY_TAG_REGEX = /<body[^]*>/i;
|
|
971
993
|
// falls back to `parseFromString` if `createHTMLDocument` cannot be used
|
|
972
|
-
|
|
994
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
995
|
+
/* istanbul ignore start */
|
|
973
996
|
var parseFromDocument = function (html, tagName) {
|
|
974
|
-
/* istanbul ignore next */
|
|
975
997
|
throw new Error('This browser does not support `document.implementation.createHTMLDocument`');
|
|
976
998
|
};
|
|
977
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
978
999
|
var parseFromString = function (html, tagName) {
|
|
979
|
-
/* istanbul ignore next */
|
|
980
1000
|
throw new Error('This browser does not support `DOMParser.prototype.parseFromString`');
|
|
981
1001
|
};
|
|
1002
|
+
/* istanbul ignore stop */
|
|
1003
|
+
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
982
1004
|
var DOMParser = typeof window === 'object' && window.DOMParser;
|
|
983
1005
|
/**
|
|
984
1006
|
* DOMParser (performance: slow).
|
|
@@ -996,10 +1018,11 @@
|
|
|
996
1018
|
* @returns - Document.
|
|
997
1019
|
*/
|
|
998
1020
|
parseFromString = function (html, tagName) {
|
|
1021
|
+
/* istanbul ignore start */
|
|
999
1022
|
if (tagName) {
|
|
1000
|
-
/* istanbul ignore next */
|
|
1001
1023
|
html = "<".concat(tagName, ">").concat(html, "</").concat(tagName, ">");
|
|
1002
1024
|
}
|
|
1025
|
+
/* istanbul ignore stop */
|
|
1003
1026
|
return domParser_1.parseFromString(html, mimeType_1);
|
|
1004
1027
|
};
|
|
1005
1028
|
parseFromDocument = parseFromString;
|
|
@@ -1009,6 +1032,7 @@
|
|
|
1009
1032
|
*
|
|
1010
1033
|
* @see https://developer.mozilla.org/docs/Web/API/DOMImplementation/createHTMLDocument
|
|
1011
1034
|
*/
|
|
1035
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1012
1036
|
if (typeof document === 'object' && document.implementation) {
|
|
1013
1037
|
var htmlDocument_1 = document.implementation.createHTMLDocument();
|
|
1014
1038
|
/**
|
|
@@ -1019,6 +1043,7 @@
|
|
|
1019
1043
|
* @returns - Document
|
|
1020
1044
|
*/
|
|
1021
1045
|
parseFromDocument = function (html, tagName) {
|
|
1046
|
+
/* istanbul ignore start */
|
|
1022
1047
|
if (tagName) {
|
|
1023
1048
|
var element = htmlDocument_1.documentElement.querySelector(tagName);
|
|
1024
1049
|
if (element) {
|
|
@@ -1026,6 +1051,7 @@
|
|
|
1026
1051
|
}
|
|
1027
1052
|
return htmlDocument_1;
|
|
1028
1053
|
}
|
|
1054
|
+
/* istanbul ignore stop */
|
|
1029
1055
|
htmlDocument_1.documentElement.innerHTML = html;
|
|
1030
1056
|
return htmlDocument_1;
|
|
1031
1057
|
};
|
|
@@ -1037,6 +1063,7 @@
|
|
|
1037
1063
|
*/
|
|
1038
1064
|
var template = typeof document === 'object' && document.createElement('template');
|
|
1039
1065
|
var parseFromTemplate;
|
|
1066
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1040
1067
|
if (template && template.content) {
|
|
1041
1068
|
/**
|
|
1042
1069
|
* Uses a template element (content fragment) to parse HTML.
|
|
@@ -1049,6 +1076,9 @@
|
|
|
1049
1076
|
return template.content.childNodes;
|
|
1050
1077
|
};
|
|
1051
1078
|
}
|
|
1079
|
+
var createNodeList = /* istanbul ignore next */ function () {
|
|
1080
|
+
return document.createDocumentFragment().childNodes;
|
|
1081
|
+
};
|
|
1052
1082
|
/**
|
|
1053
1083
|
* Parses HTML string to DOM nodes.
|
|
1054
1084
|
*
|
|
@@ -1056,23 +1086,25 @@
|
|
|
1056
1086
|
* @returns - DOM nodes.
|
|
1057
1087
|
*/
|
|
1058
1088
|
function domparser$1(html) {
|
|
1059
|
-
var _a, _b;
|
|
1089
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1060
1090
|
// Escape special characters before parsing
|
|
1061
1091
|
html = (0, utilities_1.escapeSpecialCharacters)(html);
|
|
1062
|
-
var match =
|
|
1063
|
-
var firstTagName = match
|
|
1092
|
+
var match = FIRST_TAG_REGEX.exec(html);
|
|
1093
|
+
var firstTagName = (_a = match === null || match === void 0 ? void 0 : match[1]) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
1064
1094
|
switch (firstTagName) {
|
|
1065
1095
|
case HTML: {
|
|
1066
1096
|
var doc = parseFromString(html);
|
|
1067
1097
|
// the created document may come with filler head/body elements,
|
|
1068
1098
|
// so make sure to remove them if they don't actually exist
|
|
1069
|
-
if (!
|
|
1099
|
+
if (!(0, utilities_1.hasOpenTag)(html, HEAD)) {
|
|
1070
1100
|
var element = doc.querySelector(HEAD);
|
|
1071
|
-
|
|
1101
|
+
/* istanbul ignore next */
|
|
1102
|
+
(_b = element === null || element === void 0 ? void 0 : element.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(element);
|
|
1072
1103
|
}
|
|
1073
|
-
if (!
|
|
1104
|
+
if (!(0, utilities_1.hasOpenTag)(html, BODY)) {
|
|
1074
1105
|
var element = doc.querySelector(BODY);
|
|
1075
|
-
|
|
1106
|
+
/* istanbul ignore next */
|
|
1107
|
+
(_c = element === null || element === void 0 ? void 0 : element.parentNode) === null || _c === void 0 ? void 0 : _c.removeChild(element);
|
|
1076
1108
|
}
|
|
1077
1109
|
return doc.querySelectorAll(HTML);
|
|
1078
1110
|
}
|
|
@@ -1080,18 +1112,22 @@
|
|
|
1080
1112
|
case BODY: {
|
|
1081
1113
|
var elements = parseFromDocument(html).querySelectorAll(firstTagName);
|
|
1082
1114
|
// if there's a sibling element, then return both elements
|
|
1083
|
-
if (
|
|
1084
|
-
|
|
1115
|
+
if ((0, utilities_1.hasOpenTag)(html, BODY) && (0, utilities_1.hasOpenTag)(html, HEAD)) {
|
|
1116
|
+
/* istanbul ignore next */
|
|
1117
|
+
return (_e = (_d = elements[0].parentNode) === null || _d === void 0 ? void 0 : _d.childNodes) !== null && _e !== void 0 ? _e : createNodeList();
|
|
1085
1118
|
}
|
|
1086
1119
|
return elements;
|
|
1087
1120
|
}
|
|
1088
1121
|
// low-level tag or text
|
|
1089
1122
|
default: {
|
|
1123
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1090
1124
|
if (parseFromTemplate) {
|
|
1091
1125
|
return parseFromTemplate(html);
|
|
1092
1126
|
}
|
|
1127
|
+
/* istanbul ignore start */
|
|
1093
1128
|
var element = parseFromDocument(html, BODY).querySelector(BODY);
|
|
1094
|
-
return element.childNodes;
|
|
1129
|
+
return (_f = element === null || element === void 0 ? void 0 : element.childNodes) !== null && _f !== void 0 ? _f : createNodeList();
|
|
1130
|
+
/* istanbul ignore stop */
|
|
1095
1131
|
}
|
|
1096
1132
|
}
|
|
1097
1133
|
}
|
|
@@ -1126,7 +1162,7 @@
|
|
|
1126
1162
|
return [];
|
|
1127
1163
|
}
|
|
1128
1164
|
// match directive
|
|
1129
|
-
var match =
|
|
1165
|
+
var match = DIRECTIVE_REGEX.exec(html);
|
|
1130
1166
|
var directive = match ? match[1] : undefined;
|
|
1131
1167
|
return (0, utilities_1.formatDOM)((0, domparser_1.default)(html), null, directive);
|
|
1132
1168
|
}
|
|
@@ -2688,7 +2724,7 @@
|
|
|
2688
2724
|
* @param arg - The argument to be returned.
|
|
2689
2725
|
* @returns - The input argument `arg`.
|
|
2690
2726
|
*/
|
|
2691
|
-
var returnFirstArg = function (arg) { return arg; };
|
|
2727
|
+
var returnFirstArg = function (arg) { return arg; };
|
|
2692
2728
|
exports$1.returnFirstArg = returnFirstArg;
|
|
2693
2729
|
|
|
2694
2730
|
} (utilities$1));
|
|
@@ -2742,7 +2778,7 @@
|
|
|
2742
2778
|
propName = getPropName('default' + attributeNameLowerCased);
|
|
2743
2779
|
}
|
|
2744
2780
|
props[propName] = attributeValue;
|
|
2745
|
-
switch (propertyInfo
|
|
2781
|
+
switch (propertyInfo === null || propertyInfo === void 0 ? void 0 : propertyInfo.type) {
|
|
2746
2782
|
case react_property_1.BOOLEAN:
|
|
2747
2783
|
props[propName] = true;
|
|
2748
2784
|
break;
|
|
@@ -2783,6 +2819,7 @@
|
|
|
2783
2819
|
function requireDomToReact () {
|
|
2784
2820
|
if (hasRequiredDomToReact) return domToReact;
|
|
2785
2821
|
hasRequiredDomToReact = 1;
|
|
2822
|
+
/* eslint-disable @typescript-eslint/no-unsafe-enum-comparison */
|
|
2786
2823
|
var __importDefault = (domToReact && domToReact.__importDefault) || function (mod) {
|
|
2787
2824
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
2788
2825
|
};
|
|
@@ -2804,23 +2841,24 @@
|
|
|
2804
2841
|
* @returns - String or JSX element(s).
|
|
2805
2842
|
*/
|
|
2806
2843
|
function domToReact$1(nodes, options) {
|
|
2844
|
+
var _a, _b, _c, _d, _e;
|
|
2807
2845
|
if (options === void 0) { options = {}; }
|
|
2808
2846
|
var reactElements = [];
|
|
2809
2847
|
var hasReplace = typeof options.replace === 'function';
|
|
2810
|
-
var transform = options.transform
|
|
2811
|
-
var
|
|
2848
|
+
var transform = (_a = options.transform) !== null && _a !== void 0 ? _a : utilities_1.returnFirstArg;
|
|
2849
|
+
var _f = (_b = options.library) !== null && _b !== void 0 ? _b : React, cloneElement = _f.cloneElement, createElement = _f.createElement, isValidElement = _f.isValidElement;
|
|
2812
2850
|
var nodesLength = nodes.length;
|
|
2813
2851
|
for (var index = 0; index < nodesLength; index++) {
|
|
2814
2852
|
var node = nodes[index];
|
|
2815
2853
|
// replace with custom React element (if present)
|
|
2816
2854
|
if (hasReplace) {
|
|
2817
|
-
var replaceElement = options.replace(node, index);
|
|
2855
|
+
var replaceElement = (_c = options.replace) === null || _c === void 0 ? void 0 : _c.call(options, node, index);
|
|
2818
2856
|
if (isValidElement(replaceElement)) {
|
|
2819
2857
|
// set "key" prop for sibling elements
|
|
2820
2858
|
// https://react.dev/learn/rendering-lists#rules-of-keys
|
|
2821
2859
|
if (nodesLength > 1) {
|
|
2822
2860
|
replaceElement = cloneElement(replaceElement, {
|
|
2823
|
-
key: replaceElement.key
|
|
2861
|
+
key: (_d = replaceElement.key) !== null && _d !== void 0 ? _d : index,
|
|
2824
2862
|
});
|
|
2825
2863
|
}
|
|
2826
2864
|
reactElements.push(transform(replaceElement, node, index));
|
|
@@ -2851,6 +2889,7 @@
|
|
|
2851
2889
|
if (skipAttributesToProps(element)) {
|
|
2852
2890
|
(0, utilities_1.setStyleProp)(element.attribs.style, element.attribs);
|
|
2853
2891
|
props = element.attribs;
|
|
2892
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
2854
2893
|
}
|
|
2855
2894
|
else if (element.attribs) {
|
|
2856
2895
|
props = (0, attributes_to_props_1.default)(element.attribs, element.name);
|
|
@@ -2872,8 +2911,9 @@
|
|
|
2872
2911
|
// https://react.dev/reference/react-dom/components/textarea#caveats
|
|
2873
2912
|
if (node.name === 'textarea' && node.children[0]) {
|
|
2874
2913
|
props.defaultValue = node.children[0].data;
|
|
2914
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
2875
2915
|
}
|
|
2876
|
-
else if (node.children
|
|
2916
|
+
else if ((_e = node.children) === null || _e === void 0 ? void 0 : _e.length) {
|
|
2877
2917
|
// continue recursion of creating React elements (if applicable)
|
|
2878
2918
|
children = domToReact$1(node.children, options);
|
|
2879
2919
|
}
|
|
@@ -2939,13 +2979,14 @@
|
|
|
2939
2979
|
* @returns - React element(s), empty array, or string.
|
|
2940
2980
|
*/
|
|
2941
2981
|
function HTMLReactParser(html, options) {
|
|
2982
|
+
var _a;
|
|
2942
2983
|
if (typeof html !== 'string') {
|
|
2943
2984
|
throw new TypeError('First argument must be a string');
|
|
2944
2985
|
}
|
|
2945
2986
|
if (!html) {
|
|
2946
2987
|
return [];
|
|
2947
2988
|
}
|
|
2948
|
-
return (0, dom_to_react_1.default)((0, html_dom_parser_1.default)(html, (options === null || options === void 0 ? void 0 : options.htmlparser2)
|
|
2989
|
+
return (0, dom_to_react_1.default)((0, html_dom_parser_1.default)(html, (_a = options === null || options === void 0 ? void 0 : options.htmlparser2) !== null && _a !== void 0 ? _a : domParserOptions), options);
|
|
2949
2990
|
}
|
|
2950
2991
|
|
|
2951
2992
|
} (lib$3));
|