{"version":3,"file":"TagTextareaField-CI7cQTAH.js","sources":["../../../app/javascript/components/common/Outputs/TagTextareaField.tsx"],"sourcesContent":["import React, { useImperativeHandle, forwardRef, useRef, useEffect, useState, memo } from \"react\";\nimport { getImageUrl } from \"../../../commons/assets_path\";\nimport { OutputDataArray } from \"../../../types/types\";\n\ntype Props = {\n initialContent: string;\n onContentChange?: (content: string) => void;\n outputs: OutputDataArray;\n handleFocus?: () => void;\n handleInput?: (value: string) => void;\n handleBlur?: (value: string) => void;\n handleClick?: () => void;\n name?: string;\n id?: string;\n errorClass?: string;\n style?: object;\n};\n\nexport type TagValue = {\n icon_path?: string;\n display_name: string;\n test_value: string;\n};\n\nexport type HandlerType = {\n target: React.RefObject;\n value: string;\n formatForBackend: string;\n handleInsertTag: (value: TagValue) => void;\n};\n\nconst TagTextareaField = forwardRef(\n (\n {\n initialContent,\n outputs,\n handleFocus = null,\n handleInput = null,\n handleClick = null,\n onContentChange = null, // NOTE:不要な可能性があるので後に削除するかも\n handleBlur = null,\n name = \"\",\n id = \"\",\n errorClass = \"\",\n style = {},\n },\n ref,\n ) => {\n const [value, setValue] = useState(\"\");\n const [isRefReady, setIsRefReady] = useState(false);\n const localRef = useRef(null);\n const savedRangeRef = useRef(null);\n const [saveRange, setSaveRange] = useState(null);\n\n useImperativeHandle(ref, () => ({\n target: localRef,\n formatForBackend: value,\n handleInsertTag,\n value,\n }));\n\n // キャレット位置を保存\n const saveCaretPosition = () => {\n const selection = window.getSelection();\n if (selection && selection.rangeCount > 0) {\n savedRangeRef.current = selection.getRangeAt(0);\n setSaveRange(selection.getRangeAt(0));\n }\n };\n\n // キャレット位置を復元\n const restoreCaretPosition = () => {\n const selection = window.getSelection();\n if (selection && savedRangeRef.current) {\n selection.removeAllRanges();\n selection.addRange(savedRangeRef.current);\n }\n };\n\n const isLineBlankDiv = (node: Node | null) => {\n return node ? node.nodeName === \"DIV\" && (node as HTMLElement).attributes.length === 0 : false;\n };\n\n const handleInputChange = () => {\n const editor = localRef.current;\n if (!editor) return;\n\n const selection = window.getSelection();\n if (!selection) return;\n // 文字削除時、editor内がbrのみになった時発火\n if (!editor?.textContent && editor?.childNodes.length && editor?.childNodes[0].nodeName === \"BR\") {\n const wrapper = document.createElement(\"div\");\n wrapper.appendChild(editor.childNodes[0]);\n editor.prepend(wrapper);\n }\n\n // 最初のtextNode1文字入力時に発火\n if (\n editor?.textContent?.length === 1 &&\n editor?.childNodes.length &&\n editor.childNodes[0].nodeType === Node.TEXT_NODE\n ) {\n const wrapper = document.createElement(\"div\");\n wrapper.appendChild(editor.childNodes[0]);\n editor.prepend(wrapper);\n const divNode = editor.childNodes[0];\n const range = document.createRange();\n range.setStart(divNode, 1);\n range.collapse(true);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n\n if (editor) {\n const content = editor.innerHTML;\n\n if (onContentChange) {\n onContentChange(content);\n }\n setValue(formatForBackend());\n if (handleInput) {\n handleInput(formatForBackend());\n }\n }\n saveCaretPosition();\n };\n\n const handleTagClick = (e: React.MouseEvent) => {\n const target = e.target as HTMLElement;\n if (target.className === \"removeTag\") {\n target.closest(\".react-tag-input__tag__outer\")?.remove();\n handleInputChange(); // 削除後の内容を更新\n }\n };\n\n // NOTE: HTMLエンティティの除去\n const decodeHTMLEntities = (text: string) => {\n const html = text\n .replace(//gi, \"\\n\")\n .replace(/<\\/div>/gi, \"\\n\")\n .replace(/
/gi, \"\")\n .replace(/\\n+$/, \"\");\n\n // HTMLタグをすべて除去\n const temp = document.createElement(\"textarea\");\n temp.innerHTML = html;\n const result = temp.value || \"\";\n // 不要な空白をトリミングして返す\n return result;\n };\n\n // NOTE: BEに送るために{{output}}に変換する\n const formatForBackend = () => {\n if (!localRef?.current) return \"\";\n\n const tempDiv = document.createElement(\"div\");\n tempDiv.innerHTML = localRef.current.innerHTML;\n tempDiv.innerHTML = tempDiv.innerHTML.replace(//g, \"\");\n\n // タグを探して{{}}形式に変換\n const tags = tempDiv.querySelectorAll(\".react-tag-input__tag__outer\");\n tags.forEach((tag) => {\n const tagContent = tag.querySelector(\".react-tag-input__tag__content\");\n\n if (tagContent instanceof HTMLElement) {\n // タグを{{タグ名}}形式に置換\n const displayName = tagContent.innerText;\n tag.replaceWith(`{{${displayName}}}`);\n }\n });\n tempDiv.innerHTML = tempDiv.innerHTML.replace(/\\s*(<[^>]+>)\\s*/g, \"$1\").trim();\n // {{}}内の空白や改行を削除\n tempDiv.innerHTML = tempDiv.innerHTML.replace(/{{\\s*(.*?)\\s*}}/g, (match, p1) => {\n return `{{${p1.trim()}}}`;\n });\n\n // contentEditable デフォルト機能でspanが入るので対応\n const spanNodes = tempDiv.querySelectorAll(\"span\");\n spanNodes.forEach((node) => {\n const text = node.textContent;\n if (text) {\n node.replaceWith(text);\n } else {\n node.remove();\n }\n });\n\n // NOTE明日の俺へ、\"aa\"入力して改行して\"bb\"入力して1文字目のbから削除して2文字目のbを1行目に移動させてタグ入力して改行するとバグる\n\n return decodeHTMLEntities(tempDiv.innerHTML);\n };\n\n // NOTE: タグHTMLを生成\n const tagFormat = (value: TagValue) => {\n const iconPath = value?.icon_path ? getImageUrl(value.icon_path) : \"\";\n const iconNode = iconPath ? `\"\"` : \"\";\n const removeIconPath = getImageUrl(\"images/icons/grayCancel.svg\");\n const displayName = value.display_name.replace(/{{(.*?)}}/, \"$1\");\n const testValue = value?.test_value ? `

${value.test_value}

` : \"\";\n const htmlString = `\n
\n
\n ${iconNode}\n
\n ${displayName}\n
\n ${testValue}\n \n
\n
\n `;\n\n return htmlString;\n };\n\n // アウトプットからタグを入力\n const handleInsertTag = (value: TagValue) => {\n restoreCaretPosition();\n const htmlString = tagFormat(value);\n const selection = window.getSelection();\n const editor = localRef.current;\n if (!selection || !editor) return;\n\n // カーソルがcontentEditable内にあるか判定\n const range = selection.getRangeAt(0);\n if (!editor.contains(range.commonAncestorContainer)) return;\n\n const template = document.createElement(\"template\");\n template.innerHTML = htmlString.trim();\n\n const insertNode = template.content.childNodes[0];\n if (editor.innerHTML === \"\") {\n const wrapper = document.createElement(\"div\");\n wrapper.appendChild(insertNode);\n range.insertNode(wrapper);\n } else if (\n range.startContainer === editor &&\n editor.childNodes.length === 1 &&\n isLineBlankDiv(editor.childNodes[0])\n ) {\n /*\n NOTE:タグ入力時にrange.startContainerがeditorになる時があるので\n 上記対策で行div要素をstartContainerにする処理\n */\n range.setStart(editor.childNodes[0], 0);\n range.insertNode(insertNode);\n } else if (range.startContainer.parentNode?.nodeName === \"SPAN\") {\n /*\n NOTE:ブラウザ仕様でspanタグが挿入された時、spanタグ外にキャレットを移動する。\n */\n range.setStartAfter(range.startContainer.parentNode);\n range.insertNode(insertNode);\n } else {\n range.insertNode(insertNode);\n }\n range.setStartAfter(insertNode);\n range.collapse(true);\n\n selection.removeAllRanges();\n selection.addRange(range);\n\n // 挿入後の入力内容を更新\n handleInputChange();\n };\n\n // NOTE: propsで受け取った値からアウトプットの箇所をタグにリプレイスする\n const replaceTemplateTags = () => {\n if (!initialContent) return \"\";\n\n // 改行文字 `/n` で分割し、それぞれを
でラップ\n const wrappedWithDivs = initialContent\n .split(\"\\n\")\n .map((line) => `
${line.trim() || \"
\"}
`)\n .join(\"\");\n\n // {{}}を探して置換\n const replacedText = wrappedWithDivs.replace(/{{(.*?)}}/g, (match, p1) => {\n const output = findOutputByDisplayName(p1);\n return output ? tagFormat(output as TagValue).trim() : match; // 対象外は元のテキストをそのまま保持\n });\n\n return replacedText;\n };\n // NOTE: タグへのリプレイスに必要な値をoutputsから取得\n const findOutputByDisplayName = (targetDisplayName: string) => {\n for (const item of outputs) {\n const match = item.outputs.find((output) => output.display_name === targetDisplayName);\n\n if (match) {\n return {\n display_name: match.display_name,\n test_value: match.test_value,\n icon_path: item.icon_path,\n };\n }\n }\n return {\n display_name: targetDisplayName,\n };\n };\n\n // NOTE: コピー元のフォントをリセットする\n const handlePaste = (e: React.ClipboardEvent) => {\n e.preventDefault(); // デフォルトのペースト動作を無効化\n const editor = localRef.current;\n if (!editor) return;\n // クリップボードからプレーンテキストを取得\n const text = e.clipboardData.getData(\"text/plain\");\n const textareaNode = document.createElement(\"textarea\");\n const fragment = document.createDocumentFragment();\n textareaNode.innerHTML = text;\n const copyData = textareaNode.value.split(\"\\n\");\n\n // コピー対象が複数行の場合\n if (copyData.length > 1) {\n copyData.forEach((textNode) => {\n const wrapper = document.createElement(\"div\");\n\n // tentNodeが空文字列の時は
を入れる\n if (!textNode) {\n const br = document.createElement(\"br\");\n wrapper.appendChild(br);\n } else {\n wrapper.innerText = textNode;\n }\n fragment.appendChild(wrapper);\n });\n // キャレット位置を取得してテキストを挿入\n const selection = window.getSelection();\n if (selection && selection.rangeCount > 0 && fragment.childNodes.length > 0) {\n const range = selection.getRangeAt(0);\n range.deleteContents(); // 現在の選択範囲を削除\n const lastChild = fragment.lastChild;\n\n // 同じ行に入力途中の文字列がある場合\n if (range.startContainer.nodeType === Node.TEXT_NODE) {\n const currentContainer = range.startContainer.parentNode;\n\n if (currentContainer) {\n editor.insertBefore(fragment, currentContainer.nextSibling);\n }\n } else if (!editor.textContent) {\n if (editor.childNodes[0]?.nodeName === \"BR\") {\n editor.childNodes[0].remove();\n editor.insertBefore(fragment, null);\n } else if (isLineBlankDiv(range.startContainer)) {\n const childNodes = editor.childNodes;\n if (childNodes) {\n const rowIndex = Array.from(editor.childNodes).indexOf(range.startContainer as ChildNode);\n\n localRef.current.replaceChild(fragment, editor.childNodes[rowIndex]);\n }\n } else {\n editor.insertBefore(fragment, null);\n }\n } else {\n const currentContainer = range.startContainer;\n // 連続でペーストした時に、currentContainerとeditorが同じ要素を参照して、エラーが出るため\n if (editor !== currentContainer && editor.contains(currentContainer)) {\n editor.insertBefore(fragment, currentContainer);\n }\n }\n // キャレットを挿入したテキストの後ろに移動\n if (lastChild && lastChild.nodeType === Node.ELEMENT_NODE) {\n range.setStartAfter(lastChild);\n range.collapse(true);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n }\n } else {\n // コピー対象が1行の場合\n const textNode = document.createTextNode(copyData[0]);\n fragment.appendChild(textNode);\n\n const selection = window.getSelection();\n if (selection && selection.rangeCount > 0 && fragment.childNodes.length > 0) {\n const range = selection.getRangeAt(0);\n const pasteNode = fragment.lastChild;\n range.deleteContents(); // 現在の選択範囲を削除\n range.insertNode(pasteNode!);\n range.setStartAfter(pasteNode!);\n range.collapse(true);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n }\n };\n\n const handleBlur2 = () => {\n const editor = localRef.current;\n\n if (!editor) return;\n\n // 子ノードを走査\n const childNodes = Array.from(editor.childNodes);\n const targetNodes = childNodes.filter(\n (node) => node.nodeName !== \"DIV\" || (node as HTMLElement).attributes.length !== 0,\n );\n\n if (targetNodes.length) {\n const wrapper = document.createElement(\"div\");\n targetNodes.forEach((node) => {\n wrapper.appendChild(node.cloneNode(true));\n node.remove();\n });\n localRef.current.prepend(wrapper);\n }\n };\n\n const handleTextFormattingShortcuts = (event: React.KeyboardEvent) => {\n const isBoldShortcut = (event.metaKey && event.key === \"b\") || (event.ctrlKey && event.key === \"b\");\n const isItalicShortcut = (event.metaKey && event.key === \"i\") || (event.ctrlKey && event.key === \"i\");\n const isUnderlineShortcut = (event.metaKey && event.key === \"u\") || (event.ctrlKey && event.key === \"u\");\n\n if (isBoldShortcut || isItalicShortcut || isUnderlineShortcut) {\n event.preventDefault(); // デフォルトのショートカット処理を無効化\n }\n };\n\n const getCurrentLineDiv = (range: Range) => {\n let element = range.startContainer;\n while (element) {\n if (isLineBlankDiv(element)) {\n return element;\n }\n element = element.parentNode as Node;\n }\n };\n\n useEffect(() => {\n const editor = localRef.current;\n if (editor) {\n editor.innerHTML = replaceTemplateTags();\n\n if (!editor.textContent) {\n editor.innerHTML = \"

\";\n }\n setValue(initialContent);\n }\n }, []);\n\n useEffect(() => {\n if (localRef.current) {\n setIsRefReady(true); // 初回レンダリング後にrefの設定を確定\n }\n }, []);\n\n return (\n <>\n \n handleInputChange()}\n onCompositionEnd={() => handleInputChange()}\n onClick={handleTagClick}\n onFocus={(e) => {\n if (handleFocus) {\n handleFocus();\n }\n restoreCaretPosition();\n setIsRefReady(true);\n }}\n onBlur={(e) => {\n handleBlur2();\n const result = formatForBackend();\n saveCaretPosition();\n setValue(result);\n if (handleBlur) {\n handleBlur(result);\n }\n }}\n onKeyDown={(e) => {\n const editor = localRef.current;\n if (!editor) return;\n if (e.key === \"Enter\" && e.shiftKey) {\n e.preventDefault();\n }\n handleTextFormattingShortcuts(e);\n if (e.key === \"Backspace\" || e.key === \"Delete\") {\n const selection = window.getSelection();\n\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n const startContainer = range.startContainer; // キャレットがあるノード\n const startOffset = range.startOffset; // キャレットのオフセット\n\n if (e.metaKey || e.ctrlKey) {\n e.preventDefault();\n const lineDiv = getCurrentLineDiv(range);\n const offset = range.startOffset;\n const length = startContainer.textContent?.length || 0;\n\n if (startContainer.nodeType === Node.TEXT_NODE && startOffset !== length) {\n range.setStart(startContainer, 0);\n range.setEnd(startContainer, offset);\n selection.removeAllRanges();\n selection.addRange(range);\n range.deleteContents();\n } else if (lineDiv) {\n const newDiv = document.createElement(\"div\");\n const br = document.createElement(\"br\");\n newDiv.appendChild(br);\n editor.replaceChild(newDiv, lineDiv);\n range.setStart(newDiv, 0);\n range.collapse(true);\n }\n\n selection.removeAllRanges();\n selection.addRange(range);\n } else if (startContainer.nodeType === Node.TEXT_NODE) {\n // textNode削除&carret位置の右側にタグがある時、最後の一文字の削除だけ無効化して、手動で消す\n // contentEditableのデフォルト機能で無駄なbrが入るため。\n const textNode = startContainer;\n\n // キャレットがテキストノードの末尾にある場合\n if (startOffset === textNode.textContent?.length && textNode.textContent.length === 1) {\n // テキストノードの次の兄弟ノードを取得\n const isSpan = textNode.parentElement?.nodeName === \"SPAN\";\n const parentElement = isSpan ? textNode.parentElement.parentElement : textNode.parentElement;\n const childNodes = parentElement?.childNodes;\n\n if (isLineBlankDiv(parentElement) && childNodes) {\n const target = isSpan ? textNode.parentElement : textNode;\n const textNodeIndex = Array.from(childNodes).indexOf(target as ChildNode);\n\n // テキストノードの次のノードを確認\n const nextNode = childNodes[textNodeIndex + 1];\n if (\n nextNode &&\n nextNode.nodeType === Node.ELEMENT_NODE &&\n (nextNode as HTMLElement).classList.contains(\"react-tag-input__tag__outer\")\n ) {\n e.preventDefault();\n if (isSpan) {\n parentElement.removeChild(target);\n } else {\n textNode.textContent = \"\";\n }\n }\n }\n }\n }\n }\n }\n }}\n onPaste={handlePaste}\n style={{\n outline: \"none\",\n boxShadow: \"none\",\n overflow: \"auto\",\n overflowX: \"auto\",\n whiteSpace: \"pre-wrap\",\n maxHeight: \"100%\",\n height: \"100%\",\n lineHeight: \"2.5\",\n ...style,\n }}\n />\n \n );\n },\n);\n\nexport default TagTextareaField;\n"],"names":["TagTextareaField","forwardRef","initialContent","outputs","handleFocus","handleInput","handleClick","onContentChange","handleBlur","name","id","errorClass","style","ref","value","setValue","useState","isRefReady","setIsRefReady","localRef","useRef","savedRangeRef","saveRange","setSaveRange","useImperativeHandle","handleInsertTag","saveCaretPosition","selection","restoreCaretPosition","isLineBlankDiv","node","handleInputChange","editor","wrapper","_a","divNode","range","content","formatForBackend","handleTagClick","target","decodeHTMLEntities","text","html","temp","tempDiv","tag","tagContent","displayName","match","p1","tagFormat","iconPath","getImageUrl","iconNode","removeIconPath","testValue","htmlString","template","insertNode","replaceTemplateTags","line","output","findOutputByDisplayName","targetDisplayName","item","handlePaste","textareaNode","fragment","copyData","textNode","br","lastChild","currentContainer","rowIndex","pasteNode","handleBlur2","targetNodes","handleTextFormattingShortcuts","event","isBoldShortcut","isItalicShortcut","isUnderlineShortcut","getCurrentLineDiv","element","useEffect","jsxs","Fragment","jsx","result","startContainer","startOffset","lineDiv","offset","length","newDiv","_b","isSpan","_c","parentElement","childNodes","textNodeIndex","nextNode"],"mappings":"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"}