tinymce / tinymce-vue

Official TinyMCE Vue component
MIT License
2.06k stars 207 forks source link

The link and table are not working as expected #329

Closed yihuan closed 1 year ago

yihuan commented 2 years ago

What is the current behavior? I imported the editor and used in Vue file, and the link and table menu in toolbar are not functioning while clicking it. No response and no error in console.

Please provide the steps to reproduce and if possible a minimal demo of the problem via codesandbox.io or similar. Following is my code snippet:

<template>
 <Editor
    v-model="content"
    :init="init"
    :plugins="plugins"
    :toolbar="toolbar"
    :disabled="disabled"
    :inline="inline"
    :tag-name="tagName"
    :output-format="outputFormat"
    language="zh_CN"
    :language_url="languageUrl"
    @onInit="handleInit"
    @onKeyup="handleKeyup"
    @onChange="handleChange"
  />
</template>

<script setup>
import Editor from '@tinymce/tinymce-vue'

const init = {
  height: props.height,
  menubar: props.menubar,
  branding: false
}
const plugins = 'fullscreen lists link image table code help wordcount code'
const toolbar = `fullscreen | undo redo | bold italic underline |
    forecolor backcolor | bullist numlist | link | table`
</script>

What is the expected behavior? The link and table in toolbar should be working as expected.

Which versions of TinyMCE, and which browser / OS are affected by this issue? Did this work in previous versions of TinyMCE or tinymce-vue? "@tinymce/tinymce-vue": "^3"

exalate-issue-sync[bot] commented 2 years ago

Ref: INT-2963

jscasca commented 1 year ago

Is this still an issue? Without a replication case it might be hard to understand what is happening. Your code snippet seems to be missing multiple variable. For example, v-model shouldn't be used with an outputformat other than html. Additionally, the tagName could be anything and have unspecified side effect. If you can provide a codesandbox I can further look into this

yihuan commented 1 year ago

I uploaded all the static resources to our internal CDN server, so I don't think it can be access outside. So I posted all my code here.

<template>
  <div
    v-loading="loading"
    element-loading-spinner="el-icon-loading"
    class="my-editor"
  >
    <!-- eslint-disable vue/v-on-event-hyphenation -->
    <Editor
      v-model="content"
      :init="init"
      :plugins="plugins"
      :toolbar="toolbar"
      :disabled="disabled"
      :inline="inline"
      :tag-name="tagName"
      :output-format="outputFormat"
      @onInit="handleInit"
      @onKeyup="handleKeyup"
      @onChange="handleChange"
      @onBlur="handleBlur"
    />
  </div>
</template>

<script setup>
import { onMounted, ref, watch } from 'vue'
import tinymce from 'tinymce'
import Editor from '@tinymce/tinymce-vue'
import 'tinymce/plugins/link'
import 'tinymce/plugins/table'
import { workApi } from '@/request/api'

const props = defineProps({
  value: {
    type: String
  },
  disabled: {
    type: Boolean
  },
  inline: {
    type: Boolean
  },
  tagName: {
    type: String
  },
  width: {
    type: [Number, String]
  },
  height: {
    type: [Number, String],
    default: 400
  },
  menubar: {
    type: Boolean
  },
  statusbar: {
    type: Boolean
  },
  outputFormat: {
    type: String,
    default: 'html',
    validator: (val) => ['html', 'text'].includes(val)
  },
  isFixed: {
    type: String,
    default: ''
  },
  minHeight: {
    type: Number
  },
  maxHeight: {
    type: Number
  },
  autoSave: {
    type: Boolean,
    default: true
  },
  projectId: Number,
  workBaseId: Number,
  workBaseType: Number,
  placeholder: String
})

const emit = defineEmits(['input', 'blur'])

const cdnDomain = 'https://mycdndomain.cn'
const baseUrl = cdnDomain + '/static/tinymce'

const init = {
  width: props.width,
  height: props.height,
  menubar: props.menubar,
  statusbar: props.statusbar,
  branding: false,
  base_url: baseUrl,
  plugins: ['autoresize'],
  max_height: props.maxHeight,
  paste_data_images: true,
  min_height: props.minHeight,
  placeholder: props.placeholder,
  content_style: 'img {max-width: 100%}'
}
const plugins = 'fullscreen lists link image table code wordcount code paste'
const toolbar = `fullscreen | undo redo | bold italic underline |
    forecolor backcolor | bullist numlist | link | table`

const content = ref(props.value)
const loading = ref(true)

watch(content, (val) => {
  emit('input', val)
})

watch(
  () => props.value,
  (val) => {
    content.value = val
  }
)

onMounted(() => {
  tinymce.init({})
})

const handleInit = () => {
  loading.value = false
}

// eslint-disable-next-line
const handleKeyup = (event, editor) => {}

// eslint-disable-next-line
const handleChange = (event, editor) => {}
// eslint-disable-next-line
const handleBlur = (event, editor) => {
  emit('blur', content.value)
  if (props.autoSave) {
    workApi.addOrUpdateDraft({
      content: content.value,
      projectId: props.projectId
    })
  }
}
</script>

<style lang="scss">
.tox.tox-silver-sink.tox-tinymce-aux {
  z-index: 9999 !important;
}
.my-editor {
  .tox.tox-tinymce {
    border: 1px solid $color-line;

    .tox-editor-container {
      .tox-editor-header {
        position: v-bind(isFixed);
        top: 10px;

        .tox-toolbar__primary {
          background: none;
          border-bottom: 1px solid $color-line;

          .tox-toolbar__group:not(:last-of-type) {
            border-right: 1px dashed #ccc;
          }
        }
      }
    }
  }
}
</style>
jscasca commented 1 year ago

I think your setup will have a couple of unintended side effects.

When you do import tinymce from 'tinymce' you are trying to bundle the tinymce code into your application but in your init you are pointing to the static cdn. So first you have to pick whether you are bundling the entire editor or serving from a static cdn. I strongly recommend serving it from a static cdn. You can use the tinymce-script-src editor property instead to point to your self-hosted deployment.

I believe what's happening is that the code from your bundled pieces of tinymce are conflicting with what's pulled from your cdn.

Let me know if this helps

yihuan commented 1 year ago

@jscasca Thanks a lot, jscasca. You helped a lot as what you are saying is what I didn't get before. Because I don't want to bundle it into my application, but I have to do so to make it functioning. Now I know what I missed.

It just works as you expected. Thanks.