%PDF- %PDF-
Direktori : /var/www/html/node_modules/html-react-parser/lib/ |
Current File : /var/www/html/node_modules/html-react-parser/lib/dom-to-react.js |
var React = require('react'); var attributesToProps = require('./attributes-to-props'); var utilities = require('./utilities'); var setStyleProp = utilities.setStyleProp; var canTextBeChildOfNode = utilities.canTextBeChildOfNode; /** * Converts DOM nodes to JSX element(s). * * @param {DomElement[]} nodes - DOM nodes. * @param {object} [options={}] - Options. * @param {Function} [options.replace] - Replacer. * @param {object} [options.library] - Library (React, Preact, etc.). * @returns - String or JSX element(s). */ function domToReact(nodes, options) { options = options || {}; var library = options.library || React; var cloneElement = library.cloneElement; var createElement = library.createElement; var isValidElement = library.isValidElement; var result = []; var node; var isWhitespace; var hasReplace = typeof options.replace === 'function'; var replaceElement; var props; var children; var trim = options.trim; for (var i = 0, len = nodes.length; i < len; i++) { node = nodes[i]; // replace with custom React element (if present) if (hasReplace) { replaceElement = options.replace(node); if (isValidElement(replaceElement)) { // set "key" prop for sibling elements // https://fb.me/react-warning-keys if (len > 1) { replaceElement = cloneElement(replaceElement, { key: replaceElement.key || i }); } result.push(replaceElement); continue; } } if (node.type === 'text') { isWhitespace = !node.data.trim().length; if (isWhitespace && node.parent && !canTextBeChildOfNode(node.parent)) { // We have a whitespace node that can't be nested in its parent // so skip it continue; } if (trim && isWhitespace) { // Trim is enabled and we have a whitespace node // so skip it continue; } // We have a text node that's not whitespace and it can be nested // in its parent so add it to the results result.push(node.data); continue; } props = node.attribs; if (skipAttributesToProps(node)) { setStyleProp(props.style, props); } else if (props) { props = attributesToProps(props); } children = null; switch (node.type) { case 'script': case 'style': // prevent text in <script> or <style> from being escaped // https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml if (node.children[0]) { props.dangerouslySetInnerHTML = { __html: node.children[0].data }; } break; case 'tag': // setting textarea value in children is an antipattern in React // https://reactjs.org/docs/forms.html#the-textarea-tag if (node.name === 'textarea' && node.children[0]) { props.defaultValue = node.children[0].data; } else if (node.children && node.children.length) { // continue recursion of creating React elements (if applicable) children = domToReact(node.children, options); } break; // skip all other cases (e.g., comment) default: continue; } // set "key" prop for sibling elements // https://fb.me/react-warning-keys if (len > 1) { props.key = i; } result.push(createElement(node.name, props, children)); } return result.length === 1 ? result[0] : result; } /** * Determines whether DOM element attributes should be transformed to props. * Web Components should not have their attributes transformed except for `style`. * * @param {DomElement} node * @returns - Whether node attributes should be converted to props. */ function skipAttributesToProps(node) { return ( utilities.PRESERVE_CUSTOM_ATTRIBUTES && node.type === 'tag' && utilities.isCustomComponent(node.name, node.attribs) ); } module.exports = domToReact;