web_ppt / frontend /src /hooks /usePasteTextClipboardData.ts
CatPtain's picture
Upload 339 files
89ce340 verified
raw
history blame
3.41 kB
import { storeToRefs } from 'pinia'
import { useKeyboardStore } from '@/store'
import { pasteCustomClipboardString } from '@/utils/clipboard'
import { parseText2Paragraphs } from '@/utils/textParser'
import { getImageDataURL, isSVGString, svg2File } from '@/utils/image'
import { isValidURL } from '@/utils/common'
import useCreateElement from '@/hooks/useCreateElement'
import useAddSlidesOrElements from '@/hooks/useAddSlidesOrElements'
interface PasteTextClipboardDataOptions {
onlySlide?: boolean
onlyElements?: boolean
}
/**
* 判断图片URL字符串
*
* !!!注意,你需要判断允许哪些来源的图片地址被匹配,然后自行编写正则表达式
* !!!必须确保图片来源都是合法、可靠、可控、无访问限制的
*/
const isValidImgURL = (url: string) => {
const pexels = /^https?:\/\/(?:[a-zA-Z0-9-]+\.)*pexels\.com\/[^\s]+\.(?:jpg|jpeg|png|svg|webp)(?:\?.*)?$/i.test(url)
const pptist = /^https?:\/\/(?:[a-zA-Z0-9-]+\.)*pptist\.cn\/[^\s]+\.(?:jpg|jpeg|png|svg|webp)(?:\?.*)?$/i.test(url)
return pexels || pptist
}
export default () => {
const { shiftKeyState } = storeToRefs(useKeyboardStore())
const { createTextElement, createImageElement } = useCreateElement()
const { addElementsFromData, addSlidesFromData } = useAddSlidesOrElements()
/**
* 粘贴普通文本:创建为新的文本元素
* @param text 文本
*/
const createTextElementFromClipboard = (text: string) => {
createTextElement({
left: 0,
top: 0,
width: 600,
height: 50,
}, { content: text })
}
/**
* 解析剪贴板内容,根据解析结果选择合适的粘贴方式
* @param text 剪贴板内容
* @param options 配置项:onlySlide -- 仅处理页面粘贴;onlyElements -- 仅处理元素粘贴;
*/
const pasteTextClipboardData = (text: string, options?: PasteTextClipboardDataOptions) => {
const onlySlide = options?.onlySlide || false
const onlyElements = options?.onlyElements || false
const clipboardData = pasteCustomClipboardString(text)
// 元素或页面
if (typeof clipboardData === 'object') {
const { type, data } = clipboardData
if (type === 'elements' && !onlySlide) addElementsFromData(data)
else if (type === 'slides' && !onlyElements) addSlidesFromData(data)
}
// 普通文本
else if (!onlyElements && !onlySlide) {
// 普通文字
if (shiftKeyState.value) {
const string = parseText2Paragraphs(clipboardData)
createTextElementFromClipboard(string)
}
else {
// 尝试检查是否为图片地址链接
if (isValidImgURL(clipboardData)) {
createImageElement(clipboardData)
}
// 尝试检查是否为超链接
else if (isValidURL(clipboardData)) {
createTextElementFromClipboard(`<a href="${clipboardData}" title="${clipboardData}" target="_blank">${clipboardData}</a>`)
}
// 尝试检查是否为SVG代码
else if (isSVGString(clipboardData)) {
const file = svg2File(clipboardData)
getImageDataURL(file).then(dataURL => createImageElement(dataURL))
}
// 普通文字
else {
const string = parseText2Paragraphs(clipboardData)
createTextElementFromClipboard(string)
}
}
}
}
return {
pasteTextClipboardData,
}
}