Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The page is closed, but the memory still exists #432

Open
runkobe24 opened this issue Aug 13, 2024 · 0 comments
Open

The page is closed, but the memory still exists #432

runkobe24 opened this issue Aug 13, 2024 · 0 comments

Comments

@runkobe24
Copy link

What is the current behavior?

In the vue3.x project, tinymce-vue is used. After the page is closed, the memory of tinymce-vue always exists and is not destroyed.

Please provide the steps to reproduce and if possible a minimal demo of the problem via codesandbox.io or similar.

<template>
  <div class="custom-editor">
    <Editor
      v-model="valueHtml"
      api-key="no-api-key"
      tinymce-script-src="/tinymce/tinymce.min.js"
      :init="init"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue'
import Editor from '@tinymce/tinymce-vue'
import { compressImage } from '@/lib/image'
import store from '@/store'

type EditorType = typeof Editor

interface BlobInfoType {
  blob: ()=> string
  base64: ()=> string
  blobUri: ()=> string
  filename: ()=> string
  id: ()=> string
  name: ()=> string
  uri: ()=> string
}


const props = defineProps({
  value: {
    type: String,
    default: '',
  },

  isCustomUpload: {
    type: Boolean,
    default: false
  }
})

const valueHtml = ref(props.value)

const emits = defineEmits(['update:modelValue', 'custom-upload'])

const init = {
  promotion: false,
  license_key: 'gpl',
  language: "zh_CN",
  placeholder: "在这里输入文字",
  height: 500,
  resize: "false",
  // 品牌标识隐藏
  branding: false,
  statusbar: false,
  contextmenu: false,
  // 引用自定义样式
  content_css: '/tinymce/skins/content/default/content.css',
  // 插件
  plugins: "searchreplace autolink directionality visualblocks visualchars image link media table charmap pagebreak nonbreaking anchor insertdatetime advlist lists wordcount emoticons",
  // 工具栏
  toolbar: [
    "H1 H2 H3 fontsize | forecolor backcolor bold italic underline strikethrough | alignleft aligncenter alignright alignjustify | bullist numlist | imageupload table | undo redo customInsertButton",
  ],
  font_size_formats: "12px 默认字号=14px 16px 18px 20px 22px 24px 36px",
  // 顶部的bar隐藏
  menubar: false,
  paste_data_images: true,
  image_dimensions: false,
  content_style: "img {max-width: 100%}",
  nonbreaking_force_tab: true,
  setup: (editor: EditorType) => {
    // console.log('editor', editor);
    // 特殊处理图片上传,新增一个上传按钮,屏蔽掉原来的上传方式
    editor.ui.registry.addButton('imageupload', {
      icon: 'image',
      onAction: () => {
        if (props.isCustomUpload) {
          emits('custom-upload')
          return
        }
        const imageInput = document.createElement('input');
        imageInput.setAttribute('type', 'file');
        imageInput.setAttribute('multiple', 'multiple');
        imageInput.setAttribute('accept', 'image/gif, image/jpg, image/jpeg, image/png');
        document.body.appendChild(imageInput);
        const evt = new MouseEvent('click', {
          bubbles: false,
          cancelable: true,
          view: window,
        });
        imageInput.dispatchEvent(evt);
        imageInput.addEventListener('change', async (e) => {
          const target = evt.target as HTMLInputElement;
          const files = target.files || [];
          for (let i = 0; i < files?.length; i++) {
            console.log(files[i]);
            let file = files[i];
            // console.log(file.size, '大小');
            file = await compressImage(file, { maxWidth: 750 }) as File;
            const d = await store.dispatch('uploadPic', { file: file, type: 20 });
            if (d.success) {
              editor.execCommand("mceInsertContent", false, `<img src='${d.data.url}' style="max-width: 100%;"/>`);
            }
          }
        });
        imageInput.remove();
      },
    });
  },

  images_upload_handler: async (blobInfo: BlobInfoType) => {
    // eslint-disable-next-line no-async-promise-executor
    return new Promise(async (resolve, reject) => {
      if (props.isCustomUpload) {
        emits('custom-upload')
        resolve('')
        return
      }
      const blob = blobInfo.blob()
      const newBlob = new Blob([blob])
      const newFile = await compressImage(newBlob, { maxWidth: 750 })
      const d = await store.dispatch('uploadPic', { file: newFile, type: 20 })
      if (d.success) {
        resolve(d.data.url)
      } else {
        console.error(d.msg)
        resolve('')
      }
    })
  },
}

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

const insertHtml = (value: string) => {
  valueHtml.value = value
}
defineExpose({ insertHtml, valueHtml })
</script>

<style lang="stylus">
.custom-editor {
  .tox-sidebar-wrap {
    background: #f0f2f5
  }

  .tox .tox-edit-area__iframe {
    background-color: #fff
    border: 0
    box-sizing: border-box
    flex: 1
    height: 100%
    position: absolute
    width: 375px
    margin: 0 auto
    left: 0
    right: 0
    top: 0
    bottom: 0
    margin: auto
  }
}


</style>

What is the expected behavior?
image

In edge, Collect garbage can clear the closed editor memory.

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-vue: 5.0
vue: 3.4 / vue2.x
I have tried several versions of vue and they all have this problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant