diff --git a/src/editor/init-fns/bind-event.ts b/src/editor/init-fns/bind-event.ts index 0b04226..b198303 100644 --- a/src/editor/init-fns/bind-event.ts +++ b/src/editor/init-fns/bind-event.ts @@ -45,7 +45,7 @@ function _bindChange(editor: Editor): void { compositionEnd && change(editor) }) $toolbarElem.on('click', () => { - change() + change(editor) }) } diff --git a/src/menus/link/create-panel-conf.ts b/src/menus/link/create-panel-conf.ts index 76d0c79..dbe3d43 100644 --- a/src/menus/link/create-panel-conf.ts +++ b/src/menus/link/create-panel-conf.ts @@ -6,7 +6,7 @@ import editor from '../../editor/index' import { PanelConf } from '../menu-constructors/Panel' import { getRandom } from '../../utils/util' -import $ from '../../utils/dom-core' +import $, { DomElement } from '../../utils/dom-core' import isActive from './is-active' export default function (editor: editor, text: string, link: string): PanelConf { @@ -19,13 +19,36 @@ export default function (editor: editor, text: string, link: string): PanelConf // 是否显示“删除链接” const delBtnDisplay = isActive(editor) ? 'inline-block' : 'none' + let $selectedLink: DomElement + + /** + * 选中整个链接元素 + */ + function selectLinkElem(): void { + if (!isActive(editor)) return + + const $linkElem = editor.selection.getSelectionContainerElem() + if (!$linkElem) return + editor.selection.createRangeByElem($linkElem) + editor.selection.restoreSelection() + + $selectedLink = $linkElem // 赋值给函数内全局变量 + } + /** * 插入链接 * @param text 文字 * @param link 链接 */ function insertLink(text: string, link: string): void { - editor.cmd.do('insertHTML', `${text}`) + if (isActive(editor)) { + // 选区处于链接中,则选中整个菜单,再执行 insertHTML + selectLinkElem() + editor.cmd.do('insertHTML', `${text}`) + } else { + // 选区未处于链接中,直接插入即可 + editor.cmd.do('insertHTML', `${text}`) + } } /** @@ -35,11 +58,10 @@ export default function (editor: editor, text: string, link: string): PanelConf if (!isActive(editor)) { return } - const $selectionELem = editor.selection.getSelectionContainerElem() - if (!$selectionELem) { - return - } - const selectionText = editor.selection.getSelectionText() + // 选中整个链接 + selectLinkElem() + // 用文本替换链接 + const selectionText = $selectedLink.text() editor.cmd.do('insertHTML', '' + selectionText + '') } @@ -71,8 +93,14 @@ export default function (editor: editor, text: string, link: string): PanelConf // 执行插入链接 const $link = $('#' + inputLinkId) const $text = $('#' + inputTextId) - const link = $link.val() - const text = $text.val() + let link = $link.val().trim() + let text = $text.val().trim() + + // 链接为空,则不插入 + if (!link) return + // 文本为空,则用链接代替 + if (!text) text = link + insertLink(text, link) // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭 diff --git a/src/menus/link/index.ts b/src/menus/link/index.ts index 1b452d5..ac91b2d 100644 --- a/src/menus/link/index.ts +++ b/src/menus/link/index.ts @@ -30,9 +30,9 @@ class Link extends PanelMenu implements MenuActive { if (!$linkElem) { return } - // 将该元素都包含在选取之内,以便后面整体替换 - editor.selection.createRangeByElem($linkElem) - editor.selection.restoreSelection() + + // 弹出 panel + this.createPanel($linkElem.text(), $linkElem.attr('href')) } else { // 菜单未被激活,说明选区不在链接里 if (editor.selection.isSelectionEmpty()) { diff --git a/test/fns/command-mock.ts b/test/fns/command-mock.ts index 728fe6b..a2cddb3 100644 --- a/test/fns/command-mock.ts +++ b/test/fns/command-mock.ts @@ -4,7 +4,17 @@ */ export default function (document: Document) { + /** + * 说明: + * document.execCommand 赋值为一个空函数,这是因为 jest 本身不支持 document.execCommand ,所以只能这样模拟。 + * 所以,执行这个命令,如 document.execCommand('bold'),是**不会**像浏览器一样实现加粗的。 + * + * 但是,有一个例外情况需要注意,就是 editor.cmd.do('insertHTML', xx) !!! + * 根据 src/editor/command.ts 的代码逻辑,在 jest 中执行 editor.cmd.do('insertHTML', xx) 最终会走到 `range.insertNode($(html).elems[0])` 这一行 + * 所以,可以执行成功 + */ document.execCommand = jest.fn() + document.queryCommandValue = jest.fn() document.queryCommandState = jest.fn() document.queryCommandSupported = jest.fn() diff --git a/test/menus/link.test.ts b/test/menus/link.test.ts index a1dfd57..bb86b18 100644 --- a/test/menus/link.test.ts +++ b/test/menus/link.test.ts @@ -40,6 +40,7 @@ test('link 菜单:插入链接', () => { $inputLink.val(link) $btnInsert.click() + // 此处触发 editor.cmd.do('insertHTML', xx),可以被 jest 成功执行,具体参考 mockCmdFn 的描述 expect( editor.$textElem.html().indexOf(`${text}`) ).toBeGreaterThan(0)