@templatical/editor 0.0.2 → 0.0.4
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/dist/{AiChatSidebar-XBj5Rw2l.js → AiChatSidebar-CjfhTZwo.js} +1 -1
- package/dist/{AiFeatureMenu-my1mZ9DL.js → AiFeatureMenu-K44aZa_P.js} +3 -3
- package/dist/CloudEditor-DFyuRxUV.js +926 -0
- package/dist/{CollaboratorBar-BZq_Gv38.js → CollaboratorBar-BuCEcdbB.js} +25 -21
- package/dist/{CommentsSidebar-D9oxqO6l.js → CommentsSidebar-2lcqMfIP.js} +2 -2
- package/dist/{DesignReferenceSidebar-CyHq4SWt.js → DesignReferenceSidebar-CNMu4Zrx.js} +55 -54
- package/dist/{ModuleBrowserModal-Cus2Hdwl.js → ModuleBrowserModal-CvQ0xyQf.js} +6 -6
- package/dist/{ModulePreviewCanvas-DaByXKY_.js → ModulePreviewCanvas-Be2B3Y07.js} +3 -3
- package/dist/ParagraphEditor-CcMPnbDr.js +652 -0
- package/dist/{RichTextEditorContent-BRpjJ6SV.js → RichTextEditorContent-CHJlh7HJ.js} +8 -4
- package/dist/{SaveModuleDialog-BIZBQrd8.js → SaveModuleDialog-BaaeH5Xm.js} +5 -5
- package/dist/{SnapshotHistory-Ds1-QNbx.js → SnapshotHistory-BPfjiuu1.js} +2 -2
- package/dist/{TemplateScoringPanel-C8XSk_Ys.js → TemplateScoringPanel-D58A23Vq.js} +3 -3
- package/dist/{TestEmailModal-CCVfaFgV.js → TestEmailModal-DIAlB3e_.js} +3 -3
- package/dist/{TitleEditor-V4qaEULF.js → TitleEditor-D9DPjQkX.js} +7 -7
- package/dist/{TplModal-LT3FXlgs.js → TplModal-CmTSvCY-.js} +2 -2
- package/dist/{blockTypeIcons-BujoY5Dl.js → blockTypeIcons-D1RTWOkx.js} +1 -1
- package/dist/cdn/chunks/AiChatSidebar-CmPTbTFG.js +2 -0
- package/dist/cdn/chunks/AiFeatureMenu-lxVm1RjH.js +59 -0
- package/dist/cdn/chunks/AiFeatureMenu-lxVm1RjH.js.map +1 -0
- package/dist/cdn/chunks/CloudEditor-Bmp5IlWi.js +900 -0
- package/dist/cdn/chunks/CloudEditor-Bmp5IlWi.js.map +1 -0
- package/dist/cdn/chunks/CollaboratorBar-D2PKtlOw.js +51 -0
- package/dist/cdn/chunks/CollaboratorBar-D2PKtlOw.js.map +1 -0
- package/dist/cdn/chunks/CommentsSidebar-BOelj4Ca.js +2 -0
- package/dist/cdn/chunks/DesignReferenceSidebar-Bf6rg0A7.js +2 -0
- package/dist/cdn/chunks/ModuleBrowserModal-CxDXzkKS.js +195 -0
- package/dist/cdn/chunks/ModuleBrowserModal-CxDXzkKS.js.map +1 -0
- package/dist/cdn/chunks/ModulePreviewCanvas-DEfHampA.js +107 -0
- package/dist/cdn/chunks/ModulePreviewCanvas-DEfHampA.js.map +1 -0
- package/dist/cdn/chunks/ParagraphEditor-DHdu6lb3.js +503 -0
- package/dist/cdn/chunks/ParagraphEditor-DHdu6lb3.js.map +1 -0
- package/dist/cdn/chunks/RichTextEditorContent-DWUzizsC.js +106 -0
- package/dist/cdn/chunks/RichTextEditorContent-DWUzizsC.js.map +1 -0
- package/dist/cdn/chunks/SaveModuleDialog-DVna2xUl.js +119 -0
- package/dist/cdn/chunks/SaveModuleDialog-DVna2xUl.js.map +1 -0
- package/dist/cdn/chunks/SnapshotHistory-BFF2SsTN.js +2 -0
- package/dist/cdn/chunks/TemplateScoringPanel-gi8wc_m7.js +2 -0
- package/dist/cdn/chunks/TestEmailModal-Qtd6aC-6.js +2 -0
- package/dist/cdn/chunks/TitleEditor-DDf_OcHS.js +166 -0
- package/dist/cdn/chunks/TitleEditor-DDf_OcHS.js.map +1 -0
- package/dist/cdn/chunks/_rolldown_dynamic_import_helper-DMEI4TQ3.js +9 -0
- package/dist/cdn/chunks/blockTypeIcons-BnobReQm.js +22 -0
- package/dist/cdn/chunks/blockTypeIcons-BnobReQm.js.map +1 -0
- package/dist/cdn/chunks/de-BB3dgVOc.js +700 -0
- package/dist/cdn/chunks/de-BB3dgVOc.js.map +1 -0
- package/dist/cdn/chunks/de-BvYD17KT.js +89 -0
- package/dist/cdn/chunks/de-BvYD17KT.js.map +1 -0
- package/dist/cdn/chunks/dist-B6AUkMyh.js +2 -0
- package/dist/cdn/chunks/dist-B878xb_62.js +457 -0
- package/dist/cdn/chunks/dist-B878xb_62.js.map +1 -0
- package/dist/cdn/chunks/dist-Bf1Op9A1.js +2 -0
- package/dist/cdn/chunks/dist-BkETaOfw.js +2 -0
- package/dist/cdn/chunks/dist-CJcMnY7o.js +2 -0
- package/dist/cdn/chunks/dist-CWsl6S1K.js +2 -0
- package/dist/cdn/chunks/dist-CllLxIMQ.js +2 -0
- package/dist/cdn/chunks/dist-Cs0wFwdw.js +2 -0
- package/dist/cdn/chunks/dist-DLWHlekl.js +2 -0
- package/dist/cdn/chunks/dist-DS3_HVpX.js +2 -0
- package/dist/cdn/chunks/dist-DTXopj1a.js +2 -0
- package/dist/cdn/chunks/dist-DnwLoNLm.js +2 -0
- package/dist/cdn/chunks/draggable-BQNU47zu.js +11544 -0
- package/dist/cdn/chunks/{draggable-ClUwYCFL.js.map → draggable-BQNU47zu.js.map} +1 -1
- package/dist/cdn/chunks/emojiData-BVEJHcNH.js +19 -0
- package/dist/cdn/chunks/{emojiData-6fVLNqeH.js.map → emojiData-BVEJHcNH.js.map} +1 -1
- package/dist/cdn/chunks/en-CpotcOPr.js +89 -0
- package/dist/cdn/chunks/en-CpotcOPr.js.map +1 -0
- package/dist/cdn/chunks/en-DeDcpnoS.js +700 -0
- package/dist/cdn/chunks/en-DeDcpnoS.js.map +1 -0
- package/dist/cdn/chunks/extensions-B_kcV0tK.js +419 -0
- package/dist/cdn/chunks/{extensions-BfjbWqOx.js.map → extensions-B_kcV0tK.js.map} +1 -1
- package/dist/cdn/chunks/features-ofOGnSC0.js +6700 -0
- package/dist/cdn/chunks/features-ofOGnSC0.js.map +1 -0
- package/dist/cdn/chunks/icons-bIb7PBOE.js +653 -0
- package/dist/cdn/chunks/icons-bIb7PBOE.js.map +1 -0
- package/dist/cdn/chunks/liquid.browser-C1VIYISn.js +3272 -0
- package/dist/cdn/chunks/liquid.browser-C1VIYISn.js.map +1 -0
- package/dist/cdn/chunks/media-library-BIYzV2Y2.js +6005 -0
- package/dist/cdn/chunks/media-library-BIYzV2Y2.js.map +1 -0
- package/dist/cdn/chunks/pusher-DJPhQnE8.js +2505 -0
- package/dist/cdn/chunks/pusher-DJPhQnE8.js.map +1 -0
- package/dist/cdn/chunks/readableTextColor-Cd_cgWO_.js +32 -0
- package/dist/cdn/chunks/readableTextColor-Cd_cgWO_.js.map +1 -0
- package/dist/cdn/chunks/rolldown-runtime-DPITmOBR.js +20 -0
- package/dist/cdn/chunks/src-BuW9oYtm.js +494 -0
- package/dist/cdn/chunks/src-BuW9oYtm.js.map +1 -0
- package/dist/cdn/chunks/styleConstants-1KwsBMxJ.js +57 -0
- package/dist/cdn/chunks/{styleConstants-UTJ94gco.js.map → styleConstants-1KwsBMxJ.js.map} +1 -1
- package/dist/cdn/chunks/styles-DQFExz-T.js +3222 -0
- package/dist/cdn/chunks/styles-DQFExz-T.js.map +1 -0
- package/dist/cdn/chunks/tiptap-DplY-S-k.js +14208 -0
- package/dist/cdn/chunks/{tiptap-Cya4P9CN.js.map → tiptap-DplY-S-k.js.map} +1 -1
- package/dist/cdn/editor.css +2 -1
- package/dist/cdn/editor.js +260 -1
- package/dist/cdn/editor.js.map +1 -1
- package/dist/{de-B4Ob4vCo.js → de-D7TLGIPA.js} +20 -4
- package/dist/{dist-DNjZKe2Z.js → dist-BkIys9zn.js} +1 -1
- package/dist/{en-YXsspZJG.js → en-DvtiEMwP.js} +20 -4
- package/dist/{extensions-BA4NshZQ.js → extensions-DEjfEFhD.js} +3 -3
- package/dist/keys-C0MQRs8d.js +10 -0
- package/dist/readableTextColor-LDlmVEUv.js +30 -0
- package/dist/{styleConstants-CgtFM9hQ.js → styleConstants-D4SOZGBV.js} +53 -2
- package/dist/{styles-hQgJKM4i.js → styles-CgLaxDfu.js} +1091 -1069
- package/dist/templatical-editor.css +1 -1
- package/dist/templatical-editor.js +113 -89
- package/dist/templatical-editor.umd.cjs +59 -59
- package/dist/{useEditorCore-DVp5qmtC.js → useEditorCore-CjwRMl7K.js} +1185 -1043
- package/dist/{useI18n-DzH4KXDk.js → useI18n-D6m7ZUgY.js} +2 -2
- package/dist/{useMergeTag-D9zQVE-e.js → useMergeTag-BZ3X0bNr.js} +2 -2
- package/package.json +2 -2
- package/dist/CloudEditor-BVjgKwq3.js +0 -940
- package/dist/ParagraphEditor-BSyk5B6S.js +0 -670
- package/dist/cdn/chunks/ParagraphEditor-BkJQO-ZW.js +0 -3
- package/dist/cdn/chunks/ParagraphEditor-BkJQO-ZW.js.map +0 -1
- package/dist/cdn/chunks/RichTextEditorContent-UGQorJm_.js +0 -2
- package/dist/cdn/chunks/RichTextEditorContent-UGQorJm_.js.map +0 -1
- package/dist/cdn/chunks/TitleEditor-CC3Adjai.js +0 -3
- package/dist/cdn/chunks/TitleEditor-CC3Adjai.js.map +0 -1
- package/dist/cdn/chunks/dist-0UheN8rK.js +0 -1
- package/dist/cdn/chunks/dist-55mmbGQ9.js +0 -1
- package/dist/cdn/chunks/dist-B31mxKyP.js +0 -1
- package/dist/cdn/chunks/dist-B5JI9nIg.js +0 -1
- package/dist/cdn/chunks/dist-B93vLKhU.js +0 -1
- package/dist/cdn/chunks/dist-BDt3FJvj.js +0 -1
- package/dist/cdn/chunks/dist-BJRuFHmi.js +0 -1
- package/dist/cdn/chunks/dist-BKSzrf0L.js +0 -1
- package/dist/cdn/chunks/dist-BL8c5gYQ.js +0 -1
- package/dist/cdn/chunks/dist-CYThWMP5.js +0 -1
- package/dist/cdn/chunks/dist-DxZbPJYt.js +0 -1
- package/dist/cdn/chunks/draggable-ClUwYCFL.js +0 -17
- package/dist/cdn/chunks/emojiData-6fVLNqeH.js +0 -2
- package/dist/cdn/chunks/extensions-BfjbWqOx.js +0 -2
- package/dist/cdn/chunks/icons-vmLJTaJk.js +0 -2
- package/dist/cdn/chunks/icons-vmLJTaJk.js.map +0 -1
- package/dist/cdn/chunks/rolldown-runtime-BakkzWXw.js +0 -1
- package/dist/cdn/chunks/styleConstants-UTJ94gco.js +0 -2
- package/dist/cdn/chunks/tiptap-Cya4P9CN.js +0 -145
- package/dist/cdn/chunks/useEditorCore-DRhPKq_z.js +0 -2
- package/dist/cdn/chunks/useEditorCore-DRhPKq_z.js.map +0 -1
- package/dist/cdn/chunks/useMergeTag-CBSlcqnk.js +0 -2
- package/dist/cdn/chunks/useMergeTag-CBSlcqnk.js.map +0 -1
- package/dist/i18n-ikyi28RU.js +0 -23
- package/dist/keys-8B5MFafK.js +0 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extensions-BfjbWqOx.js","names":[],"sources":["../../../src/extensions/FontSize.ts","../../../src/extensions/LetterSpacing.ts","../../../src/extensions/LineHeight.ts","../../../src/extensions/LogicMergeTagNodeView.vue","../../../src/extensions/LogicMergeTagNodeView.vue","../../../src/extensions/isNodeSelected.ts","../../../src/extensions/renderVueNodeView.ts","../../../src/extensions/LogicMergeTagNode.ts","../../../src/extensions/MergeTagNodeView.vue","../../../src/extensions/MergeTagNodeView.vue","../../../src/extensions/MergeTagNode.ts"],"sourcesContent":["import { Extension } from \"@tiptap/core\";\n\nexport interface FontSizeOptions {\n types: string[];\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n fontSize: {\n setFontSize: (size: string) => ReturnType;\n unsetFontSize: () => ReturnType;\n };\n }\n}\n\nexport const FontSize = Extension.create<FontSizeOptions>({\n name: \"fontSize\",\n\n addOptions() {\n return {\n types: [\"textStyle\"],\n };\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n fontSize: {\n default: null,\n parseHTML: (element) =>\n element.style.fontSize?.replace(/['\"]+/g, \"\") || null,\n renderHTML: (attributes) => {\n if (!attributes.fontSize) {\n return {};\n }\n return {\n style: `font-size: ${attributes.fontSize}`,\n };\n },\n },\n },\n },\n ];\n },\n\n addCommands() {\n return {\n setFontSize:\n (size: string) =>\n ({ chain }) => {\n return chain().setMark(\"textStyle\", { fontSize: size }).run();\n },\n unsetFontSize:\n () =>\n ({ chain }) => {\n return chain()\n .setMark(\"textStyle\", { fontSize: null })\n .removeEmptyTextStyle()\n .run();\n },\n };\n },\n});\n","import { Extension } from \"@tiptap/core\";\n\nexport interface LetterSpacingOptions {\n types: string[];\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n letterSpacing: {\n setLetterSpacing: (spacing: string) => ReturnType;\n unsetLetterSpacing: () => ReturnType;\n };\n }\n}\n\nexport const LetterSpacing = Extension.create<LetterSpacingOptions>({\n name: \"letterSpacing\",\n\n addOptions() {\n return {\n types: [\"textStyle\"],\n };\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n letterSpacing: {\n default: null,\n parseHTML: (element) =>\n element.style.letterSpacing?.replace(/['\"]+/g, \"\") || null,\n renderHTML: (attributes) => {\n if (!attributes.letterSpacing) {\n return {};\n }\n return {\n style: `letter-spacing: ${attributes.letterSpacing}`,\n };\n },\n },\n },\n },\n ];\n },\n\n addCommands() {\n return {\n setLetterSpacing:\n (spacing: string) =>\n ({ chain }) => {\n return chain().setMark(\"textStyle\", { letterSpacing: spacing }).run();\n },\n unsetLetterSpacing:\n () =>\n ({ chain }) => {\n return chain()\n .setMark(\"textStyle\", { letterSpacing: null })\n .removeEmptyTextStyle()\n .run();\n },\n };\n },\n});\n","import { Extension } from \"@tiptap/core\";\n\nexport interface LineHeightOptions {\n types: string[];\n defaultLineHeight: string;\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n lineHeight: {\n setLineHeight: (lineHeight: string) => ReturnType;\n unsetLineHeight: () => ReturnType;\n };\n }\n}\n\nexport const LineHeight = Extension.create<LineHeightOptions>({\n name: \"lineHeight\",\n\n addOptions() {\n return {\n types: [\"paragraph\"],\n defaultLineHeight: \"1.5\",\n };\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n lineHeight: {\n default: null,\n parseHTML: (element) => element.style.lineHeight || null,\n renderHTML: (attributes) => {\n if (!attributes.lineHeight) {\n return {};\n }\n return {\n style: `line-height: ${attributes.lineHeight}`,\n };\n },\n },\n },\n },\n ];\n },\n\n addCommands() {\n return {\n setLineHeight:\n (lineHeight: string) =>\n ({ commands }) => {\n return this.options.types.every((type) =>\n commands.updateAttributes(type, { lineHeight }),\n );\n },\n unsetLineHeight:\n () =>\n ({ commands }) => {\n return this.options.types.every((type) =>\n commands.resetAttributes(type, \"lineHeight\"),\n );\n },\n };\n },\n});\n","<script setup lang=\"ts\">\nimport { useI18n } from \"../composables/useI18n\";\nimport { useMergeTag } from \"../composables/useMergeTag\";\nimport {\n getLogicMergeTagKeyword,\n isLogicMergeTagValue,\n} from \"@templatical/types\";\nimport type { Editor } from \"@tiptap/core\";\nimport { NodeViewWrapper } from \"@tiptap/vue-3\";\nimport { computed, nextTick, ref } from \"vue\";\n\nconst props = defineProps<{\n node: {\n attrs: {\n value: string;\n keyword: string;\n };\n };\n editor: Editor;\n getPos: () => number;\n deleteNode: () => void;\n updateAttributes: (attrs: Record<string, unknown>) => void;\n}>();\n\nconst { syntax } = useMergeTag();\nconst { t } = useI18n();\n\nconst isValid = computed(() =>\n isLogicMergeTagValue(props.node.attrs.value, syntax),\n);\nconst displayKeyword = computed(() =>\n getLogicMergeTagKeyword(props.node.attrs.value, syntax),\n);\n\nconst isEditing = ref(false);\nconst editValue = ref(\"\");\nconst inputRef = ref<HTMLInputElement | null>(null);\nlet handled = false;\n\nfunction startEditing(): void {\n editValue.value = props.node.attrs.value;\n handled = false;\n isEditing.value = true;\n nextTick(() => {\n inputRef.value?.focus();\n inputRef.value?.select();\n });\n}\n\nfunction finishEditing(): void {\n if (handled) {\n return;\n }\n handled = true;\n\n const newValue = editValue.value.trim();\n if (!newValue) {\n isEditing.value = false;\n return;\n }\n\n if (newValue !== props.node.attrs.value) {\n props.updateAttributes({\n value: newValue,\n keyword: isLogicMergeTagValue(newValue, syntax)\n ? getLogicMergeTagKeyword(newValue, syntax)\n : \"\",\n });\n }\n isEditing.value = false;\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\") {\n event.preventDefault();\n finishEditing();\n } else if (event.key === \"Escape\") {\n isEditing.value = false;\n }\n}\n</script>\n\n<template>\n <NodeViewWrapper\n as=\"span\"\n :class=\"\n isValid\n ? 'tpl-logic-merge-tag-node tpl:group tpl:mx-0.5 tpl:inline-flex tpl:items-center tpl:gap-1 tpl:rounded tpl:px-1.5 tpl:py-0.5 tpl:text-[0.8em] tpl:font-bold tpl:tracking-wide tpl:uppercase tpl:select-none'\n : ''\n \"\n :style=\"\n isValid\n ? 'background-color: transparent; border: 1.5px solid color-mix(in srgb, var(--tpl-primary) 50%, transparent); color: var(--tpl-primary);'\n : ''\n \"\n contenteditable=\"false\"\n >\n <!-- Edit mode -->\n <input\n v-if=\"isEditing\"\n ref=\"inputRef\"\n v-model=\"editValue\"\n type=\"text\"\n class=\"tpl:w-40 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-0.5 tpl:py-0 tpl:text-[1em] tpl:font-medium tpl:normal-case tpl:outline-none tpl:text-[var(--tpl-primary)]\"\n @blur=\"finishEditing\"\n @keydown=\"handleKeydown\"\n />\n <!-- Display mode: valid merge tag -->\n <span\n v-else-if=\"isValid\"\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n class=\"tpl-tooltip tpl:cursor-pointer\"\n :data-tooltip=\"node.attrs.value\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ displayKeyword }}\n </span>\n <!-- Display mode: invalid (plain text) -->\n <span\n v-else\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ node.attrs.value }}\n </span>\n <button\n v-if=\"isValid\"\n type=\"button\"\n :aria-label=\"t.mergeTag.deleteMergeTag\"\n class=\"tpl-merge-tag-delete tpl:flex tpl:size-5 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-full tpl:border-none tpl:bg-transparent tpl:p-0 tpl:opacity-60 tpl:transition-all hover:tpl:opacity-100 tpl:text-[var(--tpl-primary)]\"\n contenteditable=\"false\"\n @click.stop.prevent=\"deleteNode\"\n >\n <svg\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n aria-hidden=\"true\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </NodeViewWrapper>\n</template>\n","<script setup lang=\"ts\">\nimport { useI18n } from \"../composables/useI18n\";\nimport { useMergeTag } from \"../composables/useMergeTag\";\nimport {\n getLogicMergeTagKeyword,\n isLogicMergeTagValue,\n} from \"@templatical/types\";\nimport type { Editor } from \"@tiptap/core\";\nimport { NodeViewWrapper } from \"@tiptap/vue-3\";\nimport { computed, nextTick, ref } from \"vue\";\n\nconst props = defineProps<{\n node: {\n attrs: {\n value: string;\n keyword: string;\n };\n };\n editor: Editor;\n getPos: () => number;\n deleteNode: () => void;\n updateAttributes: (attrs: Record<string, unknown>) => void;\n}>();\n\nconst { syntax } = useMergeTag();\nconst { t } = useI18n();\n\nconst isValid = computed(() =>\n isLogicMergeTagValue(props.node.attrs.value, syntax),\n);\nconst displayKeyword = computed(() =>\n getLogicMergeTagKeyword(props.node.attrs.value, syntax),\n);\n\nconst isEditing = ref(false);\nconst editValue = ref(\"\");\nconst inputRef = ref<HTMLInputElement | null>(null);\nlet handled = false;\n\nfunction startEditing(): void {\n editValue.value = props.node.attrs.value;\n handled = false;\n isEditing.value = true;\n nextTick(() => {\n inputRef.value?.focus();\n inputRef.value?.select();\n });\n}\n\nfunction finishEditing(): void {\n if (handled) {\n return;\n }\n handled = true;\n\n const newValue = editValue.value.trim();\n if (!newValue) {\n isEditing.value = false;\n return;\n }\n\n if (newValue !== props.node.attrs.value) {\n props.updateAttributes({\n value: newValue,\n keyword: isLogicMergeTagValue(newValue, syntax)\n ? getLogicMergeTagKeyword(newValue, syntax)\n : \"\",\n });\n }\n isEditing.value = false;\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\") {\n event.preventDefault();\n finishEditing();\n } else if (event.key === \"Escape\") {\n isEditing.value = false;\n }\n}\n</script>\n\n<template>\n <NodeViewWrapper\n as=\"span\"\n :class=\"\n isValid\n ? 'tpl-logic-merge-tag-node tpl:group tpl:mx-0.5 tpl:inline-flex tpl:items-center tpl:gap-1 tpl:rounded tpl:px-1.5 tpl:py-0.5 tpl:text-[0.8em] tpl:font-bold tpl:tracking-wide tpl:uppercase tpl:select-none'\n : ''\n \"\n :style=\"\n isValid\n ? 'background-color: transparent; border: 1.5px solid color-mix(in srgb, var(--tpl-primary) 50%, transparent); color: var(--tpl-primary);'\n : ''\n \"\n contenteditable=\"false\"\n >\n <!-- Edit mode -->\n <input\n v-if=\"isEditing\"\n ref=\"inputRef\"\n v-model=\"editValue\"\n type=\"text\"\n class=\"tpl:w-40 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-0.5 tpl:py-0 tpl:text-[1em] tpl:font-medium tpl:normal-case tpl:outline-none tpl:text-[var(--tpl-primary)]\"\n @blur=\"finishEditing\"\n @keydown=\"handleKeydown\"\n />\n <!-- Display mode: valid merge tag -->\n <span\n v-else-if=\"isValid\"\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n class=\"tpl-tooltip tpl:cursor-pointer\"\n :data-tooltip=\"node.attrs.value\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ displayKeyword }}\n </span>\n <!-- Display mode: invalid (plain text) -->\n <span\n v-else\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ node.attrs.value }}\n </span>\n <button\n v-if=\"isValid\"\n type=\"button\"\n :aria-label=\"t.mergeTag.deleteMergeTag\"\n class=\"tpl-merge-tag-delete tpl:flex tpl:size-5 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-full tpl:border-none tpl:bg-transparent tpl:p-0 tpl:opacity-60 tpl:transition-all hover:tpl:opacity-100 tpl:text-[var(--tpl-primary)]\"\n contenteditable=\"false\"\n @click.stop.prevent=\"deleteNode\"\n >\n <svg\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n aria-hidden=\"true\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </NodeViewWrapper>\n</template>\n","import type { Editor } from \"@tiptap/core\";\n\n/**\n * Checks whether a TipTap node of the given type is selected, or if the cursor\n * is immediately adjacent to one (for Backspace/Delete handling).\n *\n * Shared by MergeTagNode and LogicMergeTagNode keyboard shortcuts.\n */\nexport function isNodeSelected(editor: Editor, nodeTypeName: string): boolean {\n const { selection } = editor.state;\n const { $from, $to } = selection;\n\n // Check if selection contains a node of this type\n let found = false;\n editor.state.doc.nodesBetween($from.pos, $to.pos, (node) => {\n if (node.type.name === nodeTypeName) {\n found = true;\n return false;\n }\n });\n\n if (found) {\n return true;\n }\n\n // Check if cursor is right after the node (for Backspace)\n if ($from.pos > 0 && $from.nodeBefore?.type.name === nodeTypeName) {\n return true;\n }\n\n // Check if cursor is right before the node (for Delete)\n if ($from.nodeAfter?.type.name === nodeTypeName) {\n return true;\n }\n\n return false;\n}\n","import type { Component } from \"vue\";\nimport { VueNodeViewRenderer } from \"@tiptap/vue-3\";\n\n/**\n * Typed wrapper for VueNodeViewRenderer that handles the known type mismatch\n * between Vue SFC default exports and TipTap's expected component type.\n */\nexport function renderVueNodeView(component: Component) {\n return VueNodeViewRenderer(\n component as Parameters<typeof VueNodeViewRenderer>[0],\n );\n}\n","import LogicMergeTagNodeView from \"./LogicMergeTagNodeView.vue\";\nimport type { SyntaxPreset } from \"@templatical/types\";\nimport {\n getLogicMergeTagKeyword,\n isLogicMergeTagValue,\n SYNTAX_PRESETS,\n} from \"@templatical/types\";\nimport { InputRule, mergeAttributes, Node, PasteRule } from \"@tiptap/core\";\nimport { isNodeSelected } from \"./isNodeSelected\";\nimport { renderVueNodeView } from \"./renderVueNodeView\";\n\nexport interface LogicMergeTagNodeOptions {\n syntax: SyntaxPreset;\n}\n\nexport const LogicMergeTagNode = Node.create<LogicMergeTagNodeOptions>({\n name: \"logicMergeTagNode\",\n\n group: \"inline\",\n\n inline: true,\n\n atom: true,\n\n addOptions() {\n return {\n syntax: SYNTAX_PRESETS.liquid,\n };\n },\n\n addAttributes() {\n return {\n value: {\n default: \"\",\n parseHTML: (element) =>\n element.getAttribute(\"data-logic-merge-tag\") || \"\",\n },\n keyword: {\n default: \"\",\n parseHTML: (element) =>\n element.getAttribute(\"data-keyword\") || element.textContent || \"\",\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: \"span[data-logic-merge-tag]\",\n },\n ];\n },\n\n renderHTML({ node, HTMLAttributes }) {\n if (!isLogicMergeTagValue(node.attrs.value, this.options.syntax)) {\n return [\"span\", {}, node.attrs.value];\n }\n\n const keyword = getLogicMergeTagKeyword(\n node.attrs.value,\n this.options.syntax,\n );\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n \"data-logic-merge-tag\": node.attrs.value,\n \"data-keyword\": keyword,\n }),\n keyword,\n ];\n },\n\n addNodeView() {\n return renderVueNodeView(LogicMergeTagNodeView);\n },\n\n addKeyboardShortcuts() {\n return {\n Backspace: () => isNodeSelected(this.editor, this.name),\n Delete: () => isNodeSelected(this.editor, this.name),\n };\n },\n\n addInputRules() {\n const inputRegex = new RegExp(this.options.syntax.logic.source + \"$\", \"\");\n\n return [\n new InputRule({\n find: inputRegex,\n handler: ({ state, range, match }) => {\n const fullValue = match[0];\n if (!isLogicMergeTagValue(fullValue, this.options.syntax)) {\n return;\n }\n\n const keyword = getLogicMergeTagKeyword(\n fullValue,\n this.options.syntax,\n );\n\n const node = this.type.create({\n value: fullValue,\n keyword,\n });\n\n state.tr.replaceWith(range.from, range.to, node);\n },\n }),\n ];\n },\n\n addPasteRules() {\n const pasteRegex = new RegExp(this.options.syntax.logic.source, \"g\");\n\n return [\n new PasteRule({\n find: pasteRegex,\n handler: ({ state, range, match }) => {\n const fullValue = match[0];\n if (!isLogicMergeTagValue(fullValue, this.options.syntax)) {\n return;\n }\n\n const keyword = getLogicMergeTagKeyword(\n fullValue,\n this.options.syntax,\n );\n\n const node = this.type.create({\n value: fullValue,\n keyword,\n });\n\n state.tr.replaceWith(range.from, range.to, node);\n },\n }),\n ];\n },\n});\n","<script setup lang=\"ts\">\nimport { useI18n } from \"../composables/useI18n\";\nimport { useMergeTag } from \"../composables/useMergeTag\";\nimport { NodeViewWrapper } from \"@tiptap/vue-3\";\nimport { computed, nextTick, ref } from \"vue\";\n\nconst props = defineProps<{\n node: {\n attrs: {\n label: string;\n value: string;\n };\n };\n deleteNode: () => void;\n updateAttributes: (attrs: Record<string, unknown>) => void;\n}>();\n\nconst { getMergeTagLabel } = useMergeTag();\nconst { t } = useI18n();\n\nconst displayLabel = computed(() => getMergeTagLabel(props.node.attrs.value));\n\nconst isEditing = ref(false);\nconst editValue = ref(\"\");\nconst inputRef = ref<HTMLInputElement | null>(null);\n\nfunction startEditing(): void {\n editValue.value = props.node.attrs.value;\n isEditing.value = true;\n nextTick(() => {\n inputRef.value?.focus();\n inputRef.value?.select();\n });\n}\n\nfunction finishEditing(): void {\n const newValue = editValue.value.trim();\n if (newValue && newValue !== props.node.attrs.value) {\n // Update with new value and derive label from it\n props.updateAttributes({\n value: newValue,\n label: getMergeTagLabel(newValue),\n });\n }\n isEditing.value = false;\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\") {\n event.preventDefault();\n finishEditing();\n } else if (event.key === \"Escape\") {\n isEditing.value = false;\n }\n}\n</script>\n\n<template>\n <NodeViewWrapper\n as=\"span\"\n class=\"tpl-merge-tag-node tpl:group tpl:mx-0.5 tpl:inline-flex tpl:items-center tpl:gap-1 tpl:rounded tpl:px-1.5 tpl:py-0.5 tpl:text-[0.9em] tpl:font-medium tpl:select-none tpl:text-[var(--tpl-primary)]\"\n style=\"\n background-color: color-mix(in srgb, var(--tpl-primary) 20%, transparent);\n \"\n contenteditable=\"false\"\n >\n <!-- Edit mode -->\n <input\n v-if=\"isEditing\"\n ref=\"inputRef\"\n v-model=\"editValue\"\n type=\"text\"\n class=\"tpl:w-32 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-0.5 tpl:py-0 tpl:text-[1em] tpl:font-medium tpl:outline-none tpl:text-[var(--tpl-primary)]\"\n @blur=\"finishEditing\"\n @keydown=\"handleKeydown\"\n />\n <!-- Display mode -->\n <span\n v-else\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n class=\"tpl-tooltip tpl:cursor-pointer\"\n :data-tooltip=\"node.attrs.value\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ displayLabel }}\n </span>\n <button\n type=\"button\"\n :aria-label=\"t.mergeTag.deleteMergeTag\"\n class=\"tpl-merge-tag-delete tpl:flex tpl:size-5 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-full tpl:border-none tpl:bg-transparent tpl:p-0 tpl:opacity-60 tpl:transition-all hover:tpl:opacity-100 tpl:text-[var(--tpl-primary)]\"\n contenteditable=\"false\"\n @click.stop.prevent=\"deleteNode\"\n >\n <svg\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n aria-hidden=\"true\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </NodeViewWrapper>\n</template>\n","<script setup lang=\"ts\">\nimport { useI18n } from \"../composables/useI18n\";\nimport { useMergeTag } from \"../composables/useMergeTag\";\nimport { NodeViewWrapper } from \"@tiptap/vue-3\";\nimport { computed, nextTick, ref } from \"vue\";\n\nconst props = defineProps<{\n node: {\n attrs: {\n label: string;\n value: string;\n };\n };\n deleteNode: () => void;\n updateAttributes: (attrs: Record<string, unknown>) => void;\n}>();\n\nconst { getMergeTagLabel } = useMergeTag();\nconst { t } = useI18n();\n\nconst displayLabel = computed(() => getMergeTagLabel(props.node.attrs.value));\n\nconst isEditing = ref(false);\nconst editValue = ref(\"\");\nconst inputRef = ref<HTMLInputElement | null>(null);\n\nfunction startEditing(): void {\n editValue.value = props.node.attrs.value;\n isEditing.value = true;\n nextTick(() => {\n inputRef.value?.focus();\n inputRef.value?.select();\n });\n}\n\nfunction finishEditing(): void {\n const newValue = editValue.value.trim();\n if (newValue && newValue !== props.node.attrs.value) {\n // Update with new value and derive label from it\n props.updateAttributes({\n value: newValue,\n label: getMergeTagLabel(newValue),\n });\n }\n isEditing.value = false;\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\") {\n event.preventDefault();\n finishEditing();\n } else if (event.key === \"Escape\") {\n isEditing.value = false;\n }\n}\n</script>\n\n<template>\n <NodeViewWrapper\n as=\"span\"\n class=\"tpl-merge-tag-node tpl:group tpl:mx-0.5 tpl:inline-flex tpl:items-center tpl:gap-1 tpl:rounded tpl:px-1.5 tpl:py-0.5 tpl:text-[0.9em] tpl:font-medium tpl:select-none tpl:text-[var(--tpl-primary)]\"\n style=\"\n background-color: color-mix(in srgb, var(--tpl-primary) 20%, transparent);\n \"\n contenteditable=\"false\"\n >\n <!-- Edit mode -->\n <input\n v-if=\"isEditing\"\n ref=\"inputRef\"\n v-model=\"editValue\"\n type=\"text\"\n class=\"tpl:w-32 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-0.5 tpl:py-0 tpl:text-[1em] tpl:font-medium tpl:outline-none tpl:text-[var(--tpl-primary)]\"\n @blur=\"finishEditing\"\n @keydown=\"handleKeydown\"\n />\n <!-- Display mode -->\n <span\n v-else\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n class=\"tpl-tooltip tpl:cursor-pointer\"\n :data-tooltip=\"node.attrs.value\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ displayLabel }}\n </span>\n <button\n type=\"button\"\n :aria-label=\"t.mergeTag.deleteMergeTag\"\n class=\"tpl-merge-tag-delete tpl:flex tpl:size-5 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-full tpl:border-none tpl:bg-transparent tpl:p-0 tpl:opacity-60 tpl:transition-all hover:tpl:opacity-100 tpl:text-[var(--tpl-primary)]\"\n contenteditable=\"false\"\n @click.stop.prevent=\"deleteNode\"\n >\n <svg\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n aria-hidden=\"true\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </NodeViewWrapper>\n</template>\n","import MergeTagNodeView from \"./MergeTagNodeView.vue\";\nimport type { MergeTag, SyntaxPreset } from \"@templatical/types\";\nimport { getMergeTagLabel, SYNTAX_PRESETS } from \"@templatical/types\";\nimport { InputRule, mergeAttributes, Node, PasteRule } from \"@tiptap/core\";\nimport { isNodeSelected } from \"./isNodeSelected\";\nimport { renderVueNodeView } from \"./renderVueNodeView\";\n\nexport interface MergeTagNodeOptions {\n mergeTags: MergeTag[];\n syntax: SyntaxPreset;\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n mergeTagNode: {\n insertMergeTag: (attrs: MergeTag) => ReturnType;\n };\n }\n}\n\nexport const MergeTagNode = Node.create<MergeTagNodeOptions>({\n name: \"mergeTagNode\",\n\n group: \"inline\",\n\n inline: true,\n\n atom: true,\n\n addOptions() {\n return {\n mergeTags: [],\n syntax: SYNTAX_PRESETS.liquid,\n };\n },\n\n addAttributes() {\n return {\n label: {\n default: \"\",\n parseHTML: (element) =>\n element.getAttribute(\"data-label\") || element.textContent || \"\",\n },\n value: {\n default: \"\",\n parseHTML: (element) => element.getAttribute(\"data-merge-tag\") || \"\",\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: \"span[data-merge-tag]\",\n },\n ];\n },\n\n renderHTML({ node, HTMLAttributes }) {\n const label = getMergeTagLabel(node.attrs.value, this.options.mergeTags);\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n \"data-merge-tag\": node.attrs.value,\n \"data-label\": label,\n }),\n label,\n ];\n },\n\n addNodeView() {\n return renderVueNodeView(MergeTagNodeView);\n },\n\n addCommands() {\n return {\n insertMergeTag:\n (attrs: MergeTag) =>\n ({ commands }) => {\n return commands.insertContent({\n type: this.name,\n attrs,\n });\n },\n };\n },\n\n addKeyboardShortcuts() {\n return {\n Backspace: () => isNodeSelected(this.editor, this.name),\n Delete: () => isNodeSelected(this.editor, this.name),\n };\n },\n\n addInputRules() {\n const inputRegex = new RegExp(this.options.syntax.value.source + \"$\", \"\");\n\n return [\n new InputRule({\n find: inputRegex,\n handler: ({ state, range, match }) => {\n const fullValue = match[0];\n const label = getMergeTagLabel(fullValue, this.options.mergeTags);\n\n const node = this.type.create({\n label,\n value: fullValue,\n });\n\n state.tr.replaceWith(range.from, range.to, node);\n },\n }),\n ];\n },\n\n addPasteRules() {\n const pasteRegex = new RegExp(this.options.syntax.value.source, \"g\");\n\n return [\n new PasteRule({\n find: pasteRegex,\n handler: ({ state, range, match }) => {\n const fullValue = match[0];\n const label = getMergeTagLabel(fullValue, this.options.mergeTags);\n\n const node = this.type.create({\n label,\n value: fullValue,\n });\n\n state.tr.replaceWith(range.from, range.to, node);\n },\n }),\n ];\n },\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"extensions-B_kcV0tK.js","names":[],"sources":["../../../src/extensions/FontSize.ts","../../../src/extensions/LetterSpacing.ts","../../../src/extensions/LineHeight.ts","../../../src/extensions/LogicMergeTagNodeView.vue","../../../src/extensions/LogicMergeTagNodeView.vue","../../../src/extensions/isNodeSelected.ts","../../../src/extensions/renderVueNodeView.ts","../../../src/extensions/LogicMergeTagNode.ts","../../../src/extensions/MergeTagNodeView.vue","../../../src/extensions/MergeTagNodeView.vue","../../../src/extensions/MergeTagNode.ts"],"sourcesContent":["import { Extension } from \"@tiptap/core\";\n\nexport interface FontSizeOptions {\n types: string[];\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n fontSize: {\n setFontSize: (size: string) => ReturnType;\n unsetFontSize: () => ReturnType;\n };\n }\n}\n\nexport const FontSize = Extension.create<FontSizeOptions>({\n name: \"fontSize\",\n\n addOptions() {\n return {\n types: [\"textStyle\"],\n };\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n fontSize: {\n default: null,\n parseHTML: (element) =>\n element.style.fontSize?.replace(/['\"]+/g, \"\") || null,\n renderHTML: (attributes) => {\n if (!attributes.fontSize) {\n return {};\n }\n return {\n style: `font-size: ${attributes.fontSize}`,\n };\n },\n },\n },\n },\n ];\n },\n\n addCommands() {\n return {\n setFontSize:\n (size: string) =>\n ({ chain }) => {\n return chain().setMark(\"textStyle\", { fontSize: size }).run();\n },\n unsetFontSize:\n () =>\n ({ chain }) => {\n return chain()\n .setMark(\"textStyle\", { fontSize: null })\n .removeEmptyTextStyle()\n .run();\n },\n };\n },\n});\n","import { Extension } from \"@tiptap/core\";\n\nexport interface LetterSpacingOptions {\n types: string[];\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n letterSpacing: {\n setLetterSpacing: (spacing: string) => ReturnType;\n unsetLetterSpacing: () => ReturnType;\n };\n }\n}\n\nexport const LetterSpacing = Extension.create<LetterSpacingOptions>({\n name: \"letterSpacing\",\n\n addOptions() {\n return {\n types: [\"textStyle\"],\n };\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n letterSpacing: {\n default: null,\n parseHTML: (element) =>\n element.style.letterSpacing?.replace(/['\"]+/g, \"\") || null,\n renderHTML: (attributes) => {\n if (!attributes.letterSpacing) {\n return {};\n }\n return {\n style: `letter-spacing: ${attributes.letterSpacing}`,\n };\n },\n },\n },\n },\n ];\n },\n\n addCommands() {\n return {\n setLetterSpacing:\n (spacing: string) =>\n ({ chain }) => {\n return chain().setMark(\"textStyle\", { letterSpacing: spacing }).run();\n },\n unsetLetterSpacing:\n () =>\n ({ chain }) => {\n return chain()\n .setMark(\"textStyle\", { letterSpacing: null })\n .removeEmptyTextStyle()\n .run();\n },\n };\n },\n});\n","import { Extension } from \"@tiptap/core\";\n\nexport interface LineHeightOptions {\n types: string[];\n defaultLineHeight: string;\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n lineHeight: {\n setLineHeight: (lineHeight: string) => ReturnType;\n unsetLineHeight: () => ReturnType;\n };\n }\n}\n\nexport const LineHeight = Extension.create<LineHeightOptions>({\n name: \"lineHeight\",\n\n addOptions() {\n return {\n types: [\"paragraph\"],\n defaultLineHeight: \"1.5\",\n };\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n lineHeight: {\n default: null,\n parseHTML: (element) => element.style.lineHeight || null,\n renderHTML: (attributes) => {\n if (!attributes.lineHeight) {\n return {};\n }\n return {\n style: `line-height: ${attributes.lineHeight}`,\n };\n },\n },\n },\n },\n ];\n },\n\n addCommands() {\n return {\n setLineHeight:\n (lineHeight: string) =>\n ({ commands }) => {\n return this.options.types.every((type) =>\n commands.updateAttributes(type, { lineHeight }),\n );\n },\n unsetLineHeight:\n () =>\n ({ commands }) => {\n return this.options.types.every((type) =>\n commands.resetAttributes(type, \"lineHeight\"),\n );\n },\n };\n },\n});\n","<script setup lang=\"ts\">\nimport { useI18n } from \"../composables/useI18n\";\nimport { useMergeTag } from \"../composables/useMergeTag\";\nimport {\n getLogicMergeTagKeyword,\n isLogicMergeTagValue,\n} from \"@templatical/types\";\nimport type { Editor } from \"@tiptap/core\";\nimport { NodeViewWrapper } from \"@tiptap/vue-3\";\nimport { computed, nextTick, ref } from \"vue\";\n\nconst props = defineProps<{\n node: {\n attrs: {\n value: string;\n keyword: string;\n };\n };\n editor: Editor;\n getPos: () => number;\n deleteNode: () => void;\n updateAttributes: (attrs: Record<string, unknown>) => void;\n}>();\n\nconst { syntax } = useMergeTag();\nconst { t } = useI18n();\n\nconst isValid = computed(() =>\n isLogicMergeTagValue(props.node.attrs.value, syntax),\n);\nconst displayKeyword = computed(() =>\n getLogicMergeTagKeyword(props.node.attrs.value, syntax),\n);\n\nconst isEditing = ref(false);\nconst editValue = ref(\"\");\nconst inputRef = ref<HTMLInputElement | null>(null);\nlet handled = false;\n\nfunction startEditing(): void {\n editValue.value = props.node.attrs.value;\n handled = false;\n isEditing.value = true;\n nextTick(() => {\n inputRef.value?.focus();\n inputRef.value?.select();\n });\n}\n\nfunction finishEditing(): void {\n if (handled) {\n return;\n }\n handled = true;\n\n const newValue = editValue.value.trim();\n if (!newValue) {\n isEditing.value = false;\n return;\n }\n\n if (newValue !== props.node.attrs.value) {\n props.updateAttributes({\n value: newValue,\n keyword: isLogicMergeTagValue(newValue, syntax)\n ? getLogicMergeTagKeyword(newValue, syntax)\n : \"\",\n });\n }\n isEditing.value = false;\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\") {\n event.preventDefault();\n finishEditing();\n } else if (event.key === \"Escape\") {\n isEditing.value = false;\n }\n}\n</script>\n\n<template>\n <NodeViewWrapper\n as=\"span\"\n :class=\"\n isValid\n ? 'tpl-logic-merge-tag-node tpl:group tpl:mx-0.5 tpl:inline-flex tpl:items-center tpl:gap-1 tpl:rounded tpl:px-1.5 tpl:py-0.5 tpl:text-[0.8em] tpl:font-bold tpl:tracking-wide tpl:uppercase tpl:select-none'\n : ''\n \"\n :style=\"\n isValid\n ? 'background-color: transparent; border: 1.5px solid color-mix(in srgb, var(--tpl-primary) 50%, transparent); color: var(--tpl-primary);'\n : ''\n \"\n contenteditable=\"false\"\n >\n <!-- Edit mode -->\n <input\n v-if=\"isEditing\"\n ref=\"inputRef\"\n v-model=\"editValue\"\n type=\"text\"\n class=\"tpl:w-40 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-0.5 tpl:py-0 tpl:text-[1em] tpl:font-medium tpl:normal-case tpl:outline-none tpl:text-[var(--tpl-primary)]\"\n @blur=\"finishEditing\"\n @keydown=\"handleKeydown\"\n />\n <!-- Display mode: valid merge tag -->\n <span\n v-else-if=\"isValid\"\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n class=\"tpl-tooltip tpl:cursor-pointer\"\n :data-tooltip=\"node.attrs.value\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ displayKeyword }}\n </span>\n <!-- Display mode: invalid (plain text) -->\n <span\n v-else\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ node.attrs.value }}\n </span>\n <button\n v-if=\"isValid\"\n type=\"button\"\n :aria-label=\"t.mergeTag.deleteMergeTag\"\n class=\"tpl-merge-tag-delete tpl:flex tpl:size-5 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-full tpl:border-none tpl:bg-transparent tpl:p-0 tpl:opacity-60 tpl:transition-all hover:tpl:opacity-100 tpl:text-[var(--tpl-primary)]\"\n contenteditable=\"false\"\n @click.stop.prevent=\"deleteNode\"\n >\n <svg\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n aria-hidden=\"true\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </NodeViewWrapper>\n</template>\n","<script setup lang=\"ts\">\nimport { useI18n } from \"../composables/useI18n\";\nimport { useMergeTag } from \"../composables/useMergeTag\";\nimport {\n getLogicMergeTagKeyword,\n isLogicMergeTagValue,\n} from \"@templatical/types\";\nimport type { Editor } from \"@tiptap/core\";\nimport { NodeViewWrapper } from \"@tiptap/vue-3\";\nimport { computed, nextTick, ref } from \"vue\";\n\nconst props = defineProps<{\n node: {\n attrs: {\n value: string;\n keyword: string;\n };\n };\n editor: Editor;\n getPos: () => number;\n deleteNode: () => void;\n updateAttributes: (attrs: Record<string, unknown>) => void;\n}>();\n\nconst { syntax } = useMergeTag();\nconst { t } = useI18n();\n\nconst isValid = computed(() =>\n isLogicMergeTagValue(props.node.attrs.value, syntax),\n);\nconst displayKeyword = computed(() =>\n getLogicMergeTagKeyword(props.node.attrs.value, syntax),\n);\n\nconst isEditing = ref(false);\nconst editValue = ref(\"\");\nconst inputRef = ref<HTMLInputElement | null>(null);\nlet handled = false;\n\nfunction startEditing(): void {\n editValue.value = props.node.attrs.value;\n handled = false;\n isEditing.value = true;\n nextTick(() => {\n inputRef.value?.focus();\n inputRef.value?.select();\n });\n}\n\nfunction finishEditing(): void {\n if (handled) {\n return;\n }\n handled = true;\n\n const newValue = editValue.value.trim();\n if (!newValue) {\n isEditing.value = false;\n return;\n }\n\n if (newValue !== props.node.attrs.value) {\n props.updateAttributes({\n value: newValue,\n keyword: isLogicMergeTagValue(newValue, syntax)\n ? getLogicMergeTagKeyword(newValue, syntax)\n : \"\",\n });\n }\n isEditing.value = false;\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\") {\n event.preventDefault();\n finishEditing();\n } else if (event.key === \"Escape\") {\n isEditing.value = false;\n }\n}\n</script>\n\n<template>\n <NodeViewWrapper\n as=\"span\"\n :class=\"\n isValid\n ? 'tpl-logic-merge-tag-node tpl:group tpl:mx-0.5 tpl:inline-flex tpl:items-center tpl:gap-1 tpl:rounded tpl:px-1.5 tpl:py-0.5 tpl:text-[0.8em] tpl:font-bold tpl:tracking-wide tpl:uppercase tpl:select-none'\n : ''\n \"\n :style=\"\n isValid\n ? 'background-color: transparent; border: 1.5px solid color-mix(in srgb, var(--tpl-primary) 50%, transparent); color: var(--tpl-primary);'\n : ''\n \"\n contenteditable=\"false\"\n >\n <!-- Edit mode -->\n <input\n v-if=\"isEditing\"\n ref=\"inputRef\"\n v-model=\"editValue\"\n type=\"text\"\n class=\"tpl:w-40 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-0.5 tpl:py-0 tpl:text-[1em] tpl:font-medium tpl:normal-case tpl:outline-none tpl:text-[var(--tpl-primary)]\"\n @blur=\"finishEditing\"\n @keydown=\"handleKeydown\"\n />\n <!-- Display mode: valid merge tag -->\n <span\n v-else-if=\"isValid\"\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n class=\"tpl-tooltip tpl:cursor-pointer\"\n :data-tooltip=\"node.attrs.value\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ displayKeyword }}\n </span>\n <!-- Display mode: invalid (plain text) -->\n <span\n v-else\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ node.attrs.value }}\n </span>\n <button\n v-if=\"isValid\"\n type=\"button\"\n :aria-label=\"t.mergeTag.deleteMergeTag\"\n class=\"tpl-merge-tag-delete tpl:flex tpl:size-5 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-full tpl:border-none tpl:bg-transparent tpl:p-0 tpl:opacity-60 tpl:transition-all hover:tpl:opacity-100 tpl:text-[var(--tpl-primary)]\"\n contenteditable=\"false\"\n @click.stop.prevent=\"deleteNode\"\n >\n <svg\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n aria-hidden=\"true\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </NodeViewWrapper>\n</template>\n","import type { Editor } from \"@tiptap/core\";\n\n/**\n * Checks whether a TipTap node of the given type is selected, or if the cursor\n * is immediately adjacent to one (for Backspace/Delete handling).\n *\n * Shared by MergeTagNode and LogicMergeTagNode keyboard shortcuts.\n */\nexport function isNodeSelected(editor: Editor, nodeTypeName: string): boolean {\n const { selection } = editor.state;\n const { $from, $to } = selection;\n\n // Check if selection contains a node of this type\n let found = false;\n editor.state.doc.nodesBetween($from.pos, $to.pos, (node) => {\n if (node.type.name === nodeTypeName) {\n found = true;\n return false;\n }\n });\n\n if (found) {\n return true;\n }\n\n // Check if cursor is right after the node (for Backspace)\n if ($from.pos > 0 && $from.nodeBefore?.type.name === nodeTypeName) {\n return true;\n }\n\n // Check if cursor is right before the node (for Delete)\n if ($from.nodeAfter?.type.name === nodeTypeName) {\n return true;\n }\n\n return false;\n}\n","import type { Component } from \"vue\";\nimport { VueNodeViewRenderer } from \"@tiptap/vue-3\";\n\n/**\n * Typed wrapper for VueNodeViewRenderer that handles the known type mismatch\n * between Vue SFC default exports and TipTap's expected component type.\n */\nexport function renderVueNodeView(component: Component) {\n return VueNodeViewRenderer(\n component as Parameters<typeof VueNodeViewRenderer>[0],\n );\n}\n","import LogicMergeTagNodeView from \"./LogicMergeTagNodeView.vue\";\nimport type { SyntaxPreset } from \"@templatical/types\";\nimport {\n getLogicMergeTagKeyword,\n isLogicMergeTagValue,\n SYNTAX_PRESETS,\n} from \"@templatical/types\";\nimport { InputRule, mergeAttributes, Node, PasteRule } from \"@tiptap/core\";\nimport { isNodeSelected } from \"./isNodeSelected\";\nimport { renderVueNodeView } from \"./renderVueNodeView\";\n\nexport interface LogicMergeTagNodeOptions {\n syntax: SyntaxPreset;\n}\n\nexport const LogicMergeTagNode = Node.create<LogicMergeTagNodeOptions>({\n name: \"logicMergeTagNode\",\n\n group: \"inline\",\n\n inline: true,\n\n atom: true,\n\n addOptions() {\n return {\n syntax: SYNTAX_PRESETS.liquid,\n };\n },\n\n addAttributes() {\n return {\n value: {\n default: \"\",\n parseHTML: (element) =>\n element.getAttribute(\"data-logic-merge-tag\") || \"\",\n },\n keyword: {\n default: \"\",\n parseHTML: (element) =>\n element.getAttribute(\"data-keyword\") || element.textContent || \"\",\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: \"span[data-logic-merge-tag]\",\n },\n ];\n },\n\n renderHTML({ node, HTMLAttributes }) {\n if (!isLogicMergeTagValue(node.attrs.value, this.options.syntax)) {\n return [\"span\", {}, node.attrs.value];\n }\n\n const keyword = getLogicMergeTagKeyword(\n node.attrs.value,\n this.options.syntax,\n );\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n \"data-logic-merge-tag\": node.attrs.value,\n \"data-keyword\": keyword,\n }),\n keyword,\n ];\n },\n\n addNodeView() {\n return renderVueNodeView(LogicMergeTagNodeView);\n },\n\n addKeyboardShortcuts() {\n return {\n Backspace: () => isNodeSelected(this.editor, this.name),\n Delete: () => isNodeSelected(this.editor, this.name),\n };\n },\n\n addInputRules() {\n const inputRegex = new RegExp(this.options.syntax.logic.source + \"$\", \"\");\n\n return [\n new InputRule({\n find: inputRegex,\n handler: ({ state, range, match }) => {\n const fullValue = match[0];\n if (!isLogicMergeTagValue(fullValue, this.options.syntax)) {\n return;\n }\n\n const keyword = getLogicMergeTagKeyword(\n fullValue,\n this.options.syntax,\n );\n\n const node = this.type.create({\n value: fullValue,\n keyword,\n });\n\n state.tr.replaceWith(range.from, range.to, node);\n },\n }),\n ];\n },\n\n addPasteRules() {\n const pasteRegex = new RegExp(this.options.syntax.logic.source, \"g\");\n\n return [\n new PasteRule({\n find: pasteRegex,\n handler: ({ state, range, match }) => {\n const fullValue = match[0];\n if (!isLogicMergeTagValue(fullValue, this.options.syntax)) {\n return;\n }\n\n const keyword = getLogicMergeTagKeyword(\n fullValue,\n this.options.syntax,\n );\n\n const node = this.type.create({\n value: fullValue,\n keyword,\n });\n\n state.tr.replaceWith(range.from, range.to, node);\n },\n }),\n ];\n },\n});\n","<script setup lang=\"ts\">\nimport { useI18n } from \"../composables/useI18n\";\nimport { useMergeTag } from \"../composables/useMergeTag\";\nimport { NodeViewWrapper } from \"@tiptap/vue-3\";\nimport { computed, nextTick, ref } from \"vue\";\n\nconst props = defineProps<{\n node: {\n attrs: {\n label: string;\n value: string;\n };\n };\n deleteNode: () => void;\n updateAttributes: (attrs: Record<string, unknown>) => void;\n}>();\n\nconst { getMergeTagLabel } = useMergeTag();\nconst { t } = useI18n();\n\nconst displayLabel = computed(() => getMergeTagLabel(props.node.attrs.value));\n\nconst isEditing = ref(false);\nconst editValue = ref(\"\");\nconst inputRef = ref<HTMLInputElement | null>(null);\n\nfunction startEditing(): void {\n editValue.value = props.node.attrs.value;\n isEditing.value = true;\n nextTick(() => {\n inputRef.value?.focus();\n inputRef.value?.select();\n });\n}\n\nfunction finishEditing(): void {\n const newValue = editValue.value.trim();\n if (newValue && newValue !== props.node.attrs.value) {\n // Update with new value and derive label from it\n props.updateAttributes({\n value: newValue,\n label: getMergeTagLabel(newValue),\n });\n }\n isEditing.value = false;\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\") {\n event.preventDefault();\n finishEditing();\n } else if (event.key === \"Escape\") {\n isEditing.value = false;\n }\n}\n</script>\n\n<template>\n <NodeViewWrapper\n as=\"span\"\n class=\"tpl-merge-tag-node tpl:group tpl:mx-0.5 tpl:inline-flex tpl:items-center tpl:gap-1 tpl:rounded tpl:px-1.5 tpl:py-0.5 tpl:text-[0.9em] tpl:font-medium tpl:select-none tpl:text-[var(--tpl-primary)]\"\n style=\"\n background-color: color-mix(in srgb, var(--tpl-primary) 20%, transparent);\n \"\n contenteditable=\"false\"\n >\n <!-- Edit mode -->\n <input\n v-if=\"isEditing\"\n ref=\"inputRef\"\n v-model=\"editValue\"\n type=\"text\"\n class=\"tpl:w-32 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-0.5 tpl:py-0 tpl:text-[1em] tpl:font-medium tpl:outline-none tpl:text-[var(--tpl-primary)]\"\n @blur=\"finishEditing\"\n @keydown=\"handleKeydown\"\n />\n <!-- Display mode -->\n <span\n v-else\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n class=\"tpl-tooltip tpl:cursor-pointer\"\n :data-tooltip=\"node.attrs.value\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ displayLabel }}\n </span>\n <button\n type=\"button\"\n :aria-label=\"t.mergeTag.deleteMergeTag\"\n class=\"tpl-merge-tag-delete tpl:flex tpl:size-5 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-full tpl:border-none tpl:bg-transparent tpl:p-0 tpl:opacity-60 tpl:transition-all hover:tpl:opacity-100 tpl:text-[var(--tpl-primary)]\"\n contenteditable=\"false\"\n @click.stop.prevent=\"deleteNode\"\n >\n <svg\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n aria-hidden=\"true\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </NodeViewWrapper>\n</template>\n","<script setup lang=\"ts\">\nimport { useI18n } from \"../composables/useI18n\";\nimport { useMergeTag } from \"../composables/useMergeTag\";\nimport { NodeViewWrapper } from \"@tiptap/vue-3\";\nimport { computed, nextTick, ref } from \"vue\";\n\nconst props = defineProps<{\n node: {\n attrs: {\n label: string;\n value: string;\n };\n };\n deleteNode: () => void;\n updateAttributes: (attrs: Record<string, unknown>) => void;\n}>();\n\nconst { getMergeTagLabel } = useMergeTag();\nconst { t } = useI18n();\n\nconst displayLabel = computed(() => getMergeTagLabel(props.node.attrs.value));\n\nconst isEditing = ref(false);\nconst editValue = ref(\"\");\nconst inputRef = ref<HTMLInputElement | null>(null);\n\nfunction startEditing(): void {\n editValue.value = props.node.attrs.value;\n isEditing.value = true;\n nextTick(() => {\n inputRef.value?.focus();\n inputRef.value?.select();\n });\n}\n\nfunction finishEditing(): void {\n const newValue = editValue.value.trim();\n if (newValue && newValue !== props.node.attrs.value) {\n // Update with new value and derive label from it\n props.updateAttributes({\n value: newValue,\n label: getMergeTagLabel(newValue),\n });\n }\n isEditing.value = false;\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Enter\") {\n event.preventDefault();\n finishEditing();\n } else if (event.key === \"Escape\") {\n isEditing.value = false;\n }\n}\n</script>\n\n<template>\n <NodeViewWrapper\n as=\"span\"\n class=\"tpl-merge-tag-node tpl:group tpl:mx-0.5 tpl:inline-flex tpl:items-center tpl:gap-1 tpl:rounded tpl:px-1.5 tpl:py-0.5 tpl:text-[0.9em] tpl:font-medium tpl:select-none tpl:text-[var(--tpl-primary)]\"\n style=\"\n background-color: color-mix(in srgb, var(--tpl-primary) 20%, transparent);\n \"\n contenteditable=\"false\"\n >\n <!-- Edit mode -->\n <input\n v-if=\"isEditing\"\n ref=\"inputRef\"\n v-model=\"editValue\"\n type=\"text\"\n class=\"tpl:w-32 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-0.5 tpl:py-0 tpl:text-[1em] tpl:font-medium tpl:outline-none tpl:text-[var(--tpl-primary)]\"\n @blur=\"finishEditing\"\n @keydown=\"handleKeydown\"\n />\n <!-- Display mode -->\n <span\n v-else\n role=\"button\"\n tabindex=\"0\"\n :aria-label=\"t.mergeTag.editValue\"\n class=\"tpl-tooltip tpl:cursor-pointer\"\n :data-tooltip=\"node.attrs.value\"\n @click.stop=\"startEditing\"\n @keydown.enter.stop=\"startEditing\"\n @keydown.space.prevent.stop=\"startEditing\"\n >\n {{ displayLabel }}\n </span>\n <button\n type=\"button\"\n :aria-label=\"t.mergeTag.deleteMergeTag\"\n class=\"tpl-merge-tag-delete tpl:flex tpl:size-5 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-full tpl:border-none tpl:bg-transparent tpl:p-0 tpl:opacity-60 tpl:transition-all hover:tpl:opacity-100 tpl:text-[var(--tpl-primary)]\"\n contenteditable=\"false\"\n @click.stop.prevent=\"deleteNode\"\n >\n <svg\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n aria-hidden=\"true\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </NodeViewWrapper>\n</template>\n","import MergeTagNodeView from \"./MergeTagNodeView.vue\";\nimport type { MergeTag, SyntaxPreset } from \"@templatical/types\";\nimport { getMergeTagLabel, SYNTAX_PRESETS } from \"@templatical/types\";\nimport { InputRule, mergeAttributes, Node, PasteRule } from \"@tiptap/core\";\nimport { isNodeSelected } from \"./isNodeSelected\";\nimport { renderVueNodeView } from \"./renderVueNodeView\";\n\nexport interface MergeTagNodeOptions {\n mergeTags: MergeTag[];\n syntax: SyntaxPreset;\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n mergeTagNode: {\n insertMergeTag: (attrs: MergeTag) => ReturnType;\n };\n }\n}\n\nexport const MergeTagNode = Node.create<MergeTagNodeOptions>({\n name: \"mergeTagNode\",\n\n group: \"inline\",\n\n inline: true,\n\n atom: true,\n\n addOptions() {\n return {\n mergeTags: [],\n syntax: SYNTAX_PRESETS.liquid,\n };\n },\n\n addAttributes() {\n return {\n label: {\n default: \"\",\n parseHTML: (element) =>\n element.getAttribute(\"data-label\") || element.textContent || \"\",\n },\n value: {\n default: \"\",\n parseHTML: (element) => element.getAttribute(\"data-merge-tag\") || \"\",\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: \"span[data-merge-tag]\",\n },\n ];\n },\n\n renderHTML({ node, HTMLAttributes }) {\n const label = getMergeTagLabel(node.attrs.value, this.options.mergeTags);\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n \"data-merge-tag\": node.attrs.value,\n \"data-label\": label,\n }),\n label,\n ];\n },\n\n addNodeView() {\n return renderVueNodeView(MergeTagNodeView);\n },\n\n addCommands() {\n return {\n insertMergeTag:\n (attrs: MergeTag) =>\n ({ commands }) => {\n return commands.insertContent({\n type: this.name,\n attrs,\n });\n },\n };\n },\n\n addKeyboardShortcuts() {\n return {\n Backspace: () => isNodeSelected(this.editor, this.name),\n Delete: () => isNodeSelected(this.editor, this.name),\n };\n },\n\n addInputRules() {\n const inputRegex = new RegExp(this.options.syntax.value.source + \"$\", \"\");\n\n return [\n new InputRule({\n find: inputRegex,\n handler: ({ state, range, match }) => {\n const fullValue = match[0];\n const label = getMergeTagLabel(fullValue, this.options.mergeTags);\n\n const node = this.type.create({\n label,\n value: fullValue,\n });\n\n state.tr.replaceWith(range.from, range.to, node);\n },\n }),\n ];\n },\n\n addPasteRules() {\n const pasteRegex = new RegExp(this.options.syntax.value.source, \"g\");\n\n return [\n new PasteRule({\n find: pasteRegex,\n handler: ({ state, range, match }) => {\n const fullValue = match[0];\n const label = getMergeTagLabel(fullValue, this.options.mergeTags);\n\n const node = this.type.create({\n label,\n value: fullValue,\n });\n\n state.tr.replaceWith(range.from, range.to, node);\n },\n }),\n ];\n },\n});\n"],"mappings":"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"}
|