NewsletterCreator / src / components / NewsletterElements / TextElement.vue
TextElement.vue
Raw
<template>
  <BoilerplateElement :id="this.id">
    <template #german>
      <q-editor v-model="elementData.german.text" style="max-width: 100%;"
        ref="germanEditor"
        :toolbar="[
          ['left', 'center', 'right', 'justify'],
          ['bold', 'italic', 'underline', 'strike'],
          ['link', 'unordered'],
          ['removeFormat'],
          ['undo', 'redo']
        ]"
        @paste="(event) => removeUnwantedFormatting(event, $refs.germanEditor)"
      ></q-editor>
    </template>
    <template #english>
      <q-editor v-model="elementData.english.text"
        ref="englishEditor"
        :toolbar="[
          ['left', 'center', 'right', 'justify'],
          ['bold', 'italic', 'underline', 'strike'],
          ['link', 'unordered'],
          ['removeFormat'],
          ['undo', 'redo']
        ]"
        @paste="(event) => removeUnwantedFormatting(event, $refs.englishEditor)"
      ></q-editor>
    </template>
  </BoilerplateElement>
</template>

<script>
import BoilerplateElement from 'src/components/BoilerplateElement.vue'

export default {
  data () {
    return {
      elementData: this.data
    }
  },
  props: {
    id: {
      required: true
    },
    data: {
      type: Object,
      required: true
    }
  },
  components: {
    BoilerplateElement
  },
  methods: {
  // Remove unwanted formatting when pasting text
    removeUnwantedFormatting (evt, editor) {
    // Allow inputs to function normally (prevent interfering with link pasting in input fields)
      if (evt.target.nodeName === 'INPUT') return

      let text, html, onPasteStripFormattingIEPaste
      evt.preventDefault() // Prevent default paste behavior
      evt.stopPropagation() // Stop the event from bubbling

      // Function to clean HTML content, removing unwanted formatting
      function cleanHtmlContent (html) {
        // Remove comments from the HTML content
        html = html.replace(/<!--[\s\S]*?-->/g, '')
        // Create a temporary element to insert the HTML content
        const tempDiv = document.createElement('div')
        tempDiv.innerHTML = html

        // Define allowed tags (keep only these tags)
        const allowedTags = ['B', 'STRONG', 'I', 'EM', 'DEL', 'UL', 'OL', 'LI', 'A']

        // Recursively clean the nodes by removing unwanted tags and styles
        function cleanNode (node) {
          for (let i = 0; i < node.childNodes.length; i++) {
            const child = node.childNodes[i]

            // If it's an element node
            if (child.nodeType === 1) {
            // Check if the tag is not in the allowed list
              if (!allowedTags.includes(child.tagName.toUpperCase())) {
              // Replace the tag with its content (remove the tag but keep the text inside)
                const fragment = document.createDocumentFragment()
                while (child.firstChild) {
                  fragment.appendChild(child.firstChild) // Move child nodes to the fragment
                }
                node.replaceChild(fragment, child) // Replace the tag with its content
                i-- // Adjust the index after removing a node
              } else {
              // Recursively clean the allowed tags' children
                cleanNode(child)
              }
            }
          }
        }

        // Start cleaning the HTML from the root node
        cleanNode(tempDiv)

        // Return cleaned HTML as a string
        const cleanedHtml = tempDiv.innerHTML.replace(/(^\s+|\s+$)/g, '')
        return cleanedHtml
      }

      // Check if the clipboard contains HTML data
      if (evt.originalEvent && evt.originalEvent.clipboardData) {
        if (evt.originalEvent.clipboardData.types.includes('text/html')) {
          html = evt.originalEvent.clipboardData.getData('text/html')
          // Remove unwanted font-size styles
          html = html.replace(/font-size:\s*\d+(\.\d+)?(px|pt|em|rem|%);?/gi, '')
          // Clean the HTML to remove other unwanted tags and formatting
          html = cleanHtmlContent(html)
          editor.runCmd('insertHTML', html)
        } else {
        // If no HTML, use plain text fallback
          text = evt.originalEvent.clipboardData.getData('text/plain')
          editor.runCmd('insertText', text)
        }
      } else if (evt.clipboardData) {
        if (evt.clipboardData.types.includes('text/html')) {
          html = evt.clipboardData.getData('text/html')
          // Remove unwanted font-size styles
          html = html.replace(/font-size:\s*\d+(\.\d+)?(px|pt|em|rem|%);?/gi, '')
          // Clean the HTML content
          html = cleanHtmlContent(html)
          editor.runCmd('insertHTML', html)
        } else {
        // Plain text fallback
          text = evt.clipboardData.getData('text/plain')
          editor.runCmd('insertText', text)
        }
      } else if (window.clipboardData) {
      // Handle Internet Explorer-specific paste behavior
        if (!onPasteStripFormattingIEPaste) {
          onPasteStripFormattingIEPaste = true
          html = window.clipboardData.getData('Text')
          // Remove font size styles
          html = html.replace(/font-size:\s*\d+(\.\d+)?(px|pt|em|rem|%);?/gi, '')
          // Internet Explorer-specific command to insert HTML
          editor.runCmd('ms-pasteHTML', html)
        }
        onPasteStripFormattingIEPaste = false
      }
    }
  }

}
</script>

<style scroped>
.q-editor__content ul{
  margin-left: 1rem;
}
</style>