fix markdown

pull/381/merge
Pete Matsyburka 2 months ago
parent 1bb38d50a1
commit 0df0946c2a

@ -29,8 +29,15 @@
{{ optionValue(option) }} {{ optionValue(option) }}
</template> </template>
<template v-else> <template v-else>
{{ field.title || field.name || fieldNames[field.type] }} <MarkdownContent
<template v-if="field.type === 'checkbox' && !field.name"> v-if="field.title"
:text-only="true"
:string="field.title"
/>
<template v-else>
{{ field.name || fieldNames[field.type] }}
</template>
<template v-if="field.type === 'checkbox' && !field.name && !field.title">
{{ fieldIndex + 1 }} {{ fieldIndex + 1 }}
</template> </template>
<template v-else-if="!field.required && field.type !== 'checkbox'"> <template v-else-if="!field.required && field.type !== 'checkbox'">
@ -222,12 +229,14 @@
</template> </template>
<script> <script>
import MarkdownContent from './markdown_content'
import { IconTextSize, IconWritingSign, IconCalendarEvent, IconPhoto, IconCheckbox, IconPaperclip, IconSelect, IconCircleDot, IconChecks, IconCheck, IconColumns3, IconPhoneCheck, IconLetterCaseUpper, IconCreditCard, IconRubberStamp, IconSquareNumber1, IconId } from '@tabler/icons-vue' import { IconTextSize, IconWritingSign, IconCalendarEvent, IconPhoto, IconCheckbox, IconPaperclip, IconSelect, IconCircleDot, IconChecks, IconCheck, IconColumns3, IconPhoneCheck, IconLetterCaseUpper, IconCreditCard, IconRubberStamp, IconSquareNumber1, IconId } from '@tabler/icons-vue'
export default { export default {
name: 'FieldArea', name: 'FieldArea',
components: { components: {
IconPaperclip, IconPaperclip,
MarkdownContent,
IconCheck IconCheck
}, },
inject: ['t'], inject: ['t'],

@ -1,35 +1,32 @@
<template> <template>
<span> <span>
<template <span v-if="textOnly">
v-for="(item, index) in items" {{ dom.body.textContent }}
:key="index" </span>
> <template v-else>
<a
v-if="item.startsWith('<a') && item.endsWith('</a>')"
:href="sanitizeUrl(extractAttr(item, 'href'))"
rel="noopener noreferrer nofollow"
:class="extractAttr(item, 'class') || 'link'"
target="_blank"
>
{{ extractText(item) }}
</a>
<b
v-else-if="item.startsWith('<b>') || item.startsWith('<strong>')"
>
{{ extractText(item) }}
</b>
<i
v-else-if="item.startsWith('<i>') || item.startsWith('<em>')"
>
{{ extractText(item) }}
</i>
<br
v-else-if="item === '<br>' || item === '\n'"
>
<template <template
v-else v-for="(item, index) in nodes || dom.body.childNodes"
:key="index"
> >
{{ item }} <a
v-if="item.tagName === 'A' && item.getAttribute('href') !== 'undefined'"
:href="sanitizeUrl(item.getAttribute('href'))"
rel="noopener noreferrer nofollow"
:class="item.getAttribute('class') || 'link'"
target="_blank"
>
<MarkdownContent :nodes="item.childNodes" />
</a>
<component
:is="item.tagName"
v-else-if="safeTags.includes(item.tagName)"
>
<MarkdownContent :nodes="item.childNodes" />
</component>
<br v-else-if="item.tagName === 'BR' || item.nodeValue === '\n'">
<template v-else>
{{ item.textContent }}
</template>
</template> </template>
</template> </template>
</span> </span>
@ -39,8 +36,6 @@
import snarkdown from 'snarkdown' import snarkdown from 'snarkdown'
import { sanitizeUrl } from '@braintree/sanitize-url' import { sanitizeUrl } from '@braintree/sanitize-url'
const htmlSplitRegexp = /(<a.+?<\/a>|<i>.+?<\/i>|<b>.+?<\/b>|<em>.+?<\/em>|<strong>.+?<\/strong>|<br>)/
export default { export default {
name: 'MarkdownContent', name: 'MarkdownContent',
props: { props: {
@ -48,35 +43,30 @@ export default {
type: String, type: String,
required: false, required: false,
default: '' default: ''
},
nodes: {
type: [Array, Object],
require: false,
default: null
},
textOnly: {
type: Boolean,
required: false,
default: false
} }
}, },
computed: { computed: {
items () { safeTags () {
const linkParts = this.string.split(/(https?:\/\/[^\s)]+)/g) return ['UL', 'I', 'EM', 'B', 'STRONG', 'P']
},
const text = linkParts.map((part, index) => { dom () {
if (part.match(/^https?:\/\//) && !linkParts[index - 1]?.match(/\(\s*$/) && !linkParts[index + 1]?.match(/^\s*\)/)) { const text = this.string.replace(/(?<!\(\s*)(https?:\/\/[^\s)]+)(?!\s*\))/g, (url) => `[${url}](${url})`)
return `[${part}](${part})`
} else {
return part
}
}).join('')
return snarkdown(text.replace(/\n/g, '<br>')).split(htmlSplitRegexp) return new DOMParser().parseFromString(snarkdown(text.replace(/\n/g, '<br>')), 'text/html')
} }
}, },
methods: { methods: {
sanitizeUrl, sanitizeUrl
extractAttr (text, attr) {
if (text.includes(attr)) {
return text.split(attr).pop().split('"')[1]
}
},
extractText (text) {
if (text) {
return text.match(/>(.+?)</)?.[1]
}
}
} }
} }
</script> </script>

Loading…
Cancel
Save