html-react-parser
Version:
An HTML to React parser.
111 lines (97 loc) • 2.88 kB
JavaScript
var React = require('react');
var hyphenPatternRegex = /-([a-z])/g;
var CUSTOM_PROPERTY_OR_NO_HYPHEN_REGEX = /^--[a-zA-Z0-9-]+$|^[^-]+$/;
/**
* Converts a string to camelCase.
*
* @param {String} string - The string.
* @return {String}
*/
function camelCase(string) {
if (typeof string !== 'string') {
throw new TypeError('First argument must be a string');
}
// custom property or no hyphen found
if (CUSTOM_PROPERTY_OR_NO_HYPHEN_REGEX.test(string)) {
return string;
}
// convert to camelCase
return string
.toLowerCase()
.replace(hyphenPatternRegex, function(_, character) {
return character.toUpperCase();
});
}
/**
* Swap key with value in an object.
*
* @param {Object} obj - The object.
* @param {Function} [override] - The override method.
* @return {Object} - The inverted object.
*/
function invertObject(obj, override) {
if (!obj || typeof obj !== 'object') {
throw new TypeError('First argument must be an object');
}
var key;
var value;
var isOverridePresent = typeof override === 'function';
var overrides = {};
var result = {};
for (key in obj) {
value = obj[key];
if (isOverridePresent) {
overrides = override(key, value);
if (overrides && overrides.length === 2) {
result[overrides[0]] = overrides[1];
continue;
}
}
if (typeof value === 'string') {
result[value] = key;
}
}
return result;
}
/**
* Check if a given tag is a custom component.
*
* @see {@link https://github.com/facebook/react/blob/v16.6.3/packages/react-dom/src/shared/isCustomComponent.js}
*
* @param {string} tagName - The name of the html tag.
* @param {Object} props - The props being passed to the element.
* @return {boolean}
*/
function isCustomComponent(tagName, props) {
if (tagName.indexOf('-') === -1) {
return props && typeof props.is === 'string';
}
switch (tagName) {
// These are reserved SVG and MathML elements.
// We don't mind this whitelist too much because we expect it to never grow.
// The alternative is to track the namespace in a few places which is convoluted.
// https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
case 'annotation-xml':
case 'color-profile':
case 'font-face':
case 'font-face-src':
case 'font-face-uri':
case 'font-face-format':
case 'font-face-name':
case 'missing-glyph':
return false;
default:
return true;
}
}
/**
* @constant {Boolean}
* @see {@link https://reactjs.org/blog/2017/09/08/dom-attributes-in-react-16.html}
*/
var PRESERVE_CUSTOM_ATTRIBUTES = React.version.split('.')[0] >= 16;
module.exports = {
PRESERVE_CUSTOM_ATTRIBUTES: PRESERVE_CUSTOM_ATTRIBUTES,
camelCase: camelCase,
invertObject: invertObject,
isCustomComponent: isCustomComponent
};