{"version":3,"file":"index.cjs","sources":["../src/core/constants.ts","../src/core/utils.ts","../src/core/attributes.ts","../src/core/render.ts","../src/index.ts"],"sourcesContent":["export const STYLE_COMMENTS_REGEX = /\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\//g;\nexport const STYLE_RULES_REGEX =\n  /\\s*([a-z\\-]+)\\s*:\\s*((?:[^;]*url\\(.*?\\)[^;]*|[^;]*)*)\\s*(?:;|$)/gi;\n\nexport const BOOL_HTML_ATTRIBUTES =\n  \"allowFullScreen async autoFocus autoPlay checked controls default defer disabled download formNoValidate inert itemScope hidden loop multiple muted noModule noValidate open playsInline readOnly required reversed selected\";\nexport const HTML_ATTRIBUTES =\n  \"accept-charset accessKey autoCapitalize autoComplete autoCorrect autoSave cellPadding cellSpacing charSet classID colSpan contentEditable contextMenu controlsList crossOrigin dateTime defaultChecked defaultValue disablePictureInPicture disableRemotePlayback encType enterKeyHint formMethod formAction formEncType formTarget frameBorder hrefLang http-equiv imageSizes imageSrcSet inputMode itemID itemProp itemRef itemType keyParams keyType marginWidth marginHeight maxLength mediaGroup minLength radioGroup referrerPolicy rowSpan spellCheck srcDoc srcLang srcSet tabIndex useMap\";\nexport const SVG_ATTRIBUTES =\n  \"accent-height alignment-baseline allowReorder arabic-form attributeName attributeType autoReverse baseFrequency baseline-shift baseProfile calcMode cap-height clip-path clipPathUnits clip-rule color-interpolation color-interpolation-filters color-profile color-rendering contentScriptType contentStyleType diffuseConstant dominant-baseline edgeMode enable-background externalResourcesRequired fill-opacity fill-rule filterRes filterUnits flood-opacity flood-color font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical glyphRef gradientTransform gradientUnits horiz-adv-x horiz-origin-x image-rendering kernelMatrix kernelUnitLength keyPoints keySplines keyTimes lengthAdjust letter-spacing lighting-color limitingConeAngle marker-end markerHeight marker-mid marker-start markerUnits markerWidth maskContentUnits maskUnits numOctaves overline-position overline-thickness paint-order panose-1 pathLength patternContentUnits patternTransform patternUnits pointer-events pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits refX refY rendering-intent repeatCount repeatDur requiredExtensions requiredFeatures shape-rendering specularConstant specularExponent spreadMethod startOffset stdDeviation stitchTiles stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-width stroke-opacity suppressContentEditableWarning suppressHydrationWarning surfaceScale systemLanguage tableValues targetX targetY text-anchor text-decoration textLength text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic vector-effect vert-adv-y vert-origin-x vert-origin-y v-hanging v-ideographic viewBox viewTarget v-mathematical word-spacing writing-mode xChannelSelector x-height xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space xmlns:xlink yChannelSelector zoomAndPan\";\n","export function camelCase(value: string) {\n  return value.replace(/[-:](\\w)/g, (_, $1) => $1.toUpperCase());\n}\n\nexport function identity<T>(value: T): T {\n  return value;\n}\n\nexport function boolAttrValue(value: unknown, nodeName?: string) {\n  return !value || (nodeName == \"download\" ? value : !!value);\n}\n","import {\n  STYLE_COMMENTS_REGEX,\n  STYLE_RULES_REGEX,\n  HTML_ATTRIBUTES,\n  BOOL_HTML_ATTRIBUTES,\n} from \"./constants\";\nimport { camelCase, boolAttrValue } from \"./utils\";\nimport { AttributesMap, CSSProperties, Attributes } from \"./types\";\n\nexport const htmlAttrsMap = parseAttrs(HTML_ATTRIBUTES, {\n  class: \"className\",\n  for: \"htmlFor\",\n});\nexport const boolHtmlAttrsMap = parseAttrs(BOOL_HTML_ATTRIBUTES);\n\nexport function parseAttrs(\n  attrs: string,\n  initialValue?: AttributesMap\n): AttributesMap {\n  return attrs.split(\" \").reduce<AttributesMap>((acc, prop) => {\n    const value = camelCase(prop);\n\n    acc[prop.toLowerCase()] = value;\n\n    if (prop.match(/[-:]/)) {\n      acc[value.toLowerCase()] = value;\n    }\n\n    return acc;\n  }, initialValue || {});\n}\n\nexport function styleToObject(style: string): CSSProperties {\n  style = style.replace(STYLE_COMMENTS_REGEX, \"\");\n  const rules: Record<string, string | number> = {};\n  let arr: RegExpExecArray | null;\n\n  while ((arr = STYLE_RULES_REGEX.exec(style))) {\n    const key = arr[1];\n    const value = arr[2];\n    const rule = key[0] == \"-\" ? key : camelCase(key);\n\n    rules[rule] = value;\n  }\n\n  return rules;\n}\n\nexport function attrsToProps(\n  node: Element,\n  attrsMap: AttributesMap\n): Attributes {\n  return Array.from(node.attributes).reduce<Attributes>(\n    (acc, { nodeName, nodeValue }) => {\n      const defaultAttrValue = nodeValue || \"\";\n      const attrKey =\n        ![\"reset\", \"submit\"].includes(node.getAttribute(\"type\") || \"\") &&\n        [\"checked\", \"value\"].includes(nodeName)\n          ? camelCase(\"default-\" + nodeName)\n          : attrsMap[nodeName] || nodeName;\n\n      acc[attrKey] =\n        attrKey == \"style\"\n          ? defaultAttrValue\n            ? styleToObject(defaultAttrValue)\n            : {}\n          : boolHtmlAttrsMap[nodeName]\n          ? boolAttrValue(nodeValue, nodeName)\n          : defaultAttrValue;\n\n      return acc;\n    },\n    {}\n  );\n}\n","import { ReactNode, createElement, isValidElement } from \"react\";\nimport { identity } from \"./utils\";\nimport { attrsToProps, boolHtmlAttrsMap, htmlAttrsMap } from \"./attributes\";\nimport { RenderOptions, Key } from \"./types\";\n\nexport function getNodeList(html: string, _container?: HTMLElement) {\n  try {\n    _container = new DOMParser().parseFromString(html, \"text/html\").body;\n  } catch (_) {\n    _container = document.createElement(\"div\");\n    _container.innerHTML = html;\n  }\n\n  return _container.childNodes;\n}\n\nexport function renderNode(\n  node: Node,\n  key?: Key,\n  options: RenderOptions = {}\n): ReactNode {\n  const { mapNode, mapElement, components } = options;\n  const _mapNode = mapNode || identity;\n  const _node = _mapNode(node, key, options);\n\n  if (!(_node && _node instanceof Node)) {\n    return _node;\n  }\n\n  const nodeType = _node.nodeType;\n\n  if (nodeType === 3) {\n    return _node.nodeValue;\n  }\n\n  if (nodeType === 1) {\n    const { childNodes, nodeName } = _node as Element;\n    const _nodeName = nodeName.toLowerCase();\n    const children = childNodes.length\n      ? renderNodes(childNodes, options)\n      : null;\n    const props = Object.assign(\n      { key, children },\n      attrsToProps(\n        _node as Element,\n        Object.assign({}, htmlAttrsMap, boolHtmlAttrsMap, options.attrsMap)\n      )\n    );\n    const mapComponent = components?.[_nodeName];\n\n    const reactNode = mapComponent\n      ? mapComponent(props)\n      : createElement(_nodeName, props);\n\n    return mapElement && isValidElement(reactNode)\n      ? mapElement(reactNode)\n      : reactNode;\n  }\n}\n\nexport function renderNodes(\n  nodeList: NodeListOf<Node> | Node[],\n  options?: RenderOptions\n): ReactNode[] {\n  return Array.from(nodeList).reduce<ReactNode[]>(\n    (acc, node, key) => (acc.push(renderNode(node, key, options)), acc),\n    []\n  );\n}\n","import { createElement, Fragment, ReactNode } from \"react\";\nimport { SVG_ATTRIBUTES } from \"./core/constants\";\nimport { identity } from \"./core/utils\";\nimport { renderNode, renderNodes, getNodeList } from \"./core/render\";\nimport { parseAttrs } from \"./core/attributes\";\nimport { ParseOptions } from \"./core/types\";\n\nconst typeErrorMessage = \"HTML must be a string\";\nfunction checkTypeError(html: unknown, message: string) {\n  if (typeof html !== \"string\") {\n    throw new TypeError(message);\n  }\n}\n\nfunction parse(html: string, options: ParseOptions = {}) {\n  let node: ReactNode = null;\n\n  try {\n    checkTypeError(html, typeErrorMessage);\n\n    html = (options.sanitize || identity)(html);\n\n    checkTypeError(html, \"Sanitized \" + typeErrorMessage);\n\n    node = createElement(\n      Fragment,\n      {},\n      html && renderNodes(getNodeList(html), options)\n    );\n  } catch (error) {\n    const onError = options.onError;\n\n    if (onError?.call) {\n      onError(error, html);\n    }\n  }\n\n  return node;\n}\n\nexport * from \"./core/types\";\nexport { parse, parseAttrs, renderNodes, renderNode, SVG_ATTRIBUTES };\n"],"names":["STYLE_COMMENTS_REGEX","STYLE_RULES_REGEX","camelCase","value","replace","_","$1","toUpperCase","identity","htmlAttrsMap","parseAttrs","class","for","boolHtmlAttrsMap","attrs","initialValue","split","reduce","acc","prop","toLowerCase","match","renderNode","node","key","options","mapElement","components","mapNode","_node","Node","nodeType","nodeValue","childNodes","nodeName","children","length","renderNodes","props","Object","assign","attrsMap","Array","from","attributes","_ref","defaultAttrValue","attrKey","includes","getAttribute","style","arr","rules","exec","styleToObject","boolAttrValue","attrsToProps","_nodeName","reactNode","mapComponent","createElement","isValidElement","nodeList","push","html","message","TypeError","checkTypeError","sanitize","Fragment","getNodeList","_container","DOMParser","parseFromString","body","document","innerHTML","error","onError","call"],"mappings":"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"}