diff --git a/src/utils/prosemirror/utils.ts b/src/utils/prosemirror/utils.ts index 94494b62..902fd2c1 100644 --- a/src/utils/prosemirror/utils.ts +++ b/src/utils/prosemirror/utils.ts @@ -137,6 +137,12 @@ export const isActiveMark = (marks: Mark[], markType: string) => { return false } +export const markActive = (state: EditorState, type: MarkType) => { + const { from, $from, to, empty } = state.selection + if (empty) return type.isInSet(state.storedMarks || $from.marks()) + return state.doc.rangeHasMark(from, to, type) +} + export const getAttrValueInSelection = (view: EditorView, attr: string) => { const { selection, doc } = view.state const { from, to } = selection diff --git a/src/views/Editor/Toolbar/ElementStylePanel/TextStylePanel.vue b/src/views/Editor/Toolbar/ElementStylePanel/TextStylePanel.vue index daddc3ea..f0e3f44a 100644 --- a/src/views/Editor/Toolbar/ElementStylePanel/TextStylePanel.vue +++ b/src/views/Editor/Toolbar/ElementStylePanel/TextStylePanel.vue @@ -239,14 +239,15 @@ import { defineComponent, ref, watch } from 'vue' import { storeToRefs } from 'pinia' import { useMainStore, useSlidesStore } from '@/store' +import { PPTTextElement } from '@/types/slides' import emitter, { EmitterEvents, RichTextCommand } from '@/utils/emitter' import { WEB_FONTS } from '@/configs/font' import useHistorySnapshot from '@/hooks/useHistorySnapshot' +import { message } from 'ant-design-vue' import ElementOpacity from '../common/ElementOpacity.vue' import ElementOutline from '../common/ElementOutline.vue' import ElementShadow from '../common/ElementShadow.vue' -import { PPTTextElement } from '@/types/slides' const presetStyles = [ { @@ -397,6 +398,10 @@ export default defineComponent({ linkPopoverVisible.value = true } const updateLink = (link: string) => { + if (link) { + const linkRegExp = /^(https?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/ + if (!linkRegExp.test(link)) return message.error('不是正确的网页链接地址') + } emitRichTextCommand('link', link) linkPopoverVisible.value = false } diff --git a/src/views/components/element/ProsemirrorEditor.vue b/src/views/components/element/ProsemirrorEditor.vue index 5bbed222..432dd094 100644 --- a/src/views/components/element/ProsemirrorEditor.vue +++ b/src/views/components/element/ProsemirrorEditor.vue @@ -13,7 +13,7 @@ import { useMainStore } from '@/store' import { EditorView } from 'prosemirror-view' import { toggleMark, wrapIn, selectAll } from 'prosemirror-commands' import { initProsemirrorEditor, createDocument } from '@/utils/prosemirror' -import { findNodesWithSameMark, getTextAttrs, autoSelectAll, addMark } from '@/utils/prosemirror/utils' +import { findNodesWithSameMark, getTextAttrs, autoSelectAll, addMark, markActive } from '@/utils/prosemirror/utils' import emitter, { EmitterEvents, RichTextCommand } from '@/utils/emitter' import { alignmentCommand } from '@/utils/prosemirror/commands/setTextAlign' import { toggleList } from '@/utils/prosemirror/commands/toggleList' @@ -205,6 +205,13 @@ export default defineComponent({ } else editorView.dispatch(editorView.state.tr.removeMark(result.from.pos, result.to.pos + 1, markType)) } + else if (markActive(editorView.state, markType)) { + if (item.value) { + const mark = editorView.state.schema.marks.link.create({ href: item.value, title: item.value }) + addMark(editorView, mark) + } + else toggleMark(markType)(editorView.state, editorView.dispatch) + } else if (item.value) { autoSelectAll(editorView) toggleMark(markType, { href: item.value, title: item.value })(editorView.state, editorView.dispatch)