{"version":3,"file":"use-handlers.mjs","names":[],"sources":["../../../../../../packages/components/upload/src/use-handlers.ts"],"sourcesContent":["import { nextTick, watch } from 'vue'\nimport { isNil } from 'lodash-unified'\nimport { useVModel } from '@vueuse/core'\nimport { debugWarn, throwError } from '@element-plus/utils'\nimport { genFileId } from './upload'\n\nimport type { ShallowRef } from 'vue'\nimport type {\n  UploadContentInstance,\n  UploadContentProps,\n} from './upload-content'\nimport type {\n  UploadFile,\n  UploadFiles,\n  UploadProps,\n  UploadRawFile,\n  UploadStatus,\n} from './upload'\n\nconst SCOPE = 'ElUpload'\n\nconst revokeFileObjectURL = (file: UploadFile) => {\n  if (file.url?.startsWith('blob:')) {\n    URL.revokeObjectURL(file.url)\n  }\n}\n\nexport const useHandlers = (\n  props: UploadProps &\n    Required<\n      Pick<\n        UploadProps,\n        | 'listType'\n        | 'onChange'\n        | 'onError'\n        | 'onProgress'\n        | 'onSuccess'\n        | 'onRemove'\n      >\n    >,\n  uploadRef: ShallowRef<UploadContentInstance | undefined>\n) => {\n  const uploadFiles = useVModel(\n    props as Omit<UploadProps, 'fileList'> & { fileList: UploadFiles },\n    'fileList',\n    undefined,\n    { passive: true }\n  )\n\n  const getFile = (rawFile: UploadRawFile) =>\n    uploadFiles.value.find((file) => file.uid === rawFile.uid)\n\n  function abort(file?: UploadFile) {\n    uploadRef.value?.abort(file)\n  }\n\n  function clearFiles(\n    /** @default ['ready', 'uploading', 'success', 'fail'] */\n    states: UploadStatus[] = ['ready', 'uploading', 'success', 'fail']\n  ) {\n    uploadFiles.value = uploadFiles.value.filter(\n      (row) => !states.includes(row.status)\n    )\n  }\n\n  function removeFile(file: UploadFile) {\n    uploadFiles.value = uploadFiles.value.filter(\n      (uploadFile) => uploadFile.uid !== file.uid\n    )\n  }\n\n  const emitChange = (file: UploadFile) => {\n    nextTick(() => props.onChange(file, uploadFiles.value))\n  }\n\n  const handleError: UploadContentProps['onError'] = (err, rawFile) => {\n    const file = getFile(rawFile)\n    if (!file) return\n\n    console.error(err)\n    file.status = 'fail'\n    removeFile(file)\n    props.onError(err, file, uploadFiles.value)\n    emitChange(file)\n  }\n\n  const handleProgress: UploadContentProps['onProgress'] = (evt, rawFile) => {\n    const file = getFile(rawFile)\n    if (!file) return\n\n    props.onProgress(evt, file, uploadFiles.value)\n    file.status = 'uploading'\n    file.percentage = Math.round(evt.percent)\n  }\n\n  const handleSuccess: UploadContentProps['onSuccess'] = (\n    response,\n    rawFile\n  ) => {\n    const file = getFile(rawFile)\n    if (!file) return\n\n    file.status = 'success'\n    file.response = response\n    props.onSuccess(response, file, uploadFiles.value)\n    emitChange(file)\n  }\n\n  const handleStart: UploadContentProps['onStart'] = (file) => {\n    if (isNil(file.uid)) file.uid = genFileId()\n    const uploadFile: UploadFile = {\n      name: file.name,\n      percentage: 0,\n      status: 'ready',\n      size: file.size,\n      raw: file,\n      uid: file.uid,\n    }\n    if (props.listType === 'picture-card' || props.listType === 'picture') {\n      try {\n        uploadFile.url = URL.createObjectURL(file)\n      } catch (err: unknown) {\n        debugWarn(SCOPE, (err as Error).message)\n        props.onError(err as Error, uploadFile, uploadFiles.value)\n      }\n    }\n    uploadFiles.value = [...uploadFiles.value, uploadFile]\n    emitChange(uploadFile)\n  }\n\n  const handleRemove: UploadContentProps['onRemove'] = async (\n    file\n  ): Promise<void> => {\n    const uploadFile = file instanceof File ? getFile(file) : file\n    if (!uploadFile) throwError(SCOPE, 'file to be removed not found')\n\n    const doRemove = (file: UploadFile) => {\n      abort(file)\n      removeFile(file)\n      props.onRemove(file, uploadFiles.value)\n      revokeFileObjectURL(file)\n    }\n\n    if (props.beforeRemove) {\n      const before = await props.beforeRemove(uploadFile, uploadFiles.value)\n      if (before !== false) doRemove(uploadFile)\n    } else {\n      doRemove(uploadFile)\n    }\n  }\n\n  function submit() {\n    uploadFiles.value\n      .filter(({ status }) => status === 'ready')\n      .forEach(({ raw }) => raw && uploadRef.value?.upload(raw))\n  }\n\n  watch(\n    () => props.listType,\n    (val) => {\n      if (val !== 'picture-card' && val !== 'picture') {\n        return\n      }\n\n      uploadFiles.value = uploadFiles.value.map((file) => {\n        const { raw, url } = file\n        if (!url && raw) {\n          try {\n            file.url = URL.createObjectURL(raw)\n          } catch (err: unknown) {\n            props.onError(err as Error, file, uploadFiles.value)\n          }\n        }\n        return file\n      })\n    }\n  )\n\n  watch(\n    uploadFiles,\n    (files) => {\n      for (const file of files) {\n        file.uid ||= genFileId()\n        file.status ||= 'success'\n      }\n    },\n    { immediate: true, deep: true }\n  )\n\n  return {\n    /** @description two-way binding ref from props `fileList` */\n    uploadFiles,\n    abort,\n    clearFiles,\n    handleError,\n    handleProgress,\n    handleStart,\n    handleSuccess,\n    handleRemove,\n    submit,\n    revokeFileObjectURL,\n  }\n}\n"],"mappings":"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"}