@@ -7,7 +7,7 @@ import Editor from '../../editor/index'
7
7
import { PanelConf } from '../menu-constructors/Panel'
8
8
import { getRandom } from '../../utils/util'
9
9
import $ , { DomElement } from '../../utils/dom-core'
10
- import isActive from './is-active'
10
+ import isActive , { getParentNodeA , EXTRA_TAG } from './is-active'
11
11
import { insertHtml } from './util'
12
12
13
13
export default function ( editor : Editor , text : string , link : string ) : PanelConf {
@@ -78,9 +78,35 @@ export default function (editor: Editor, text: string, link: string): PanelConf
78
78
}
79
79
// 选中整个链接
80
80
selectLinkElem ( )
81
- // 用文本替换链接
82
- const selectionText = $selectedLink . text ( )
83
- editor . cmd . do ( 'insertHTML' , '<span>' + selectionText + '</span>' )
81
+
82
+ /**
83
+ * 替换链接
84
+ *
85
+ * 两种情况
86
+ * 1. 特殊标签里嵌套a,也要保留特殊标签:<b><a></a></b> 先加粗后添加链接
87
+ * 2. a标签里面可能会含有其他元素如:b, i等,要保留: <a><b></b></a> 先添加链接后加粗
88
+ */
89
+
90
+ if ( $selectedLink . getNodeName ( ) === 'A' ) {
91
+ const linkElem = $selectedLink . elems [ 0 ]
92
+ const linkParentNode = linkElem . parentElement
93
+
94
+ // 判断父级元素是不是特殊元素
95
+ if ( linkParentNode && EXTRA_TAG . includes ( linkParentNode . nodeName ) ) {
96
+ // 将特殊元素的内容设置为a标签的内容
97
+ linkParentNode . innerHTML = linkElem . innerHTML
98
+ } else {
99
+ // 如果父级不是特殊元素,直接设置内容
100
+ editor . cmd . do ( 'insertHTML' , '<span>' + linkElem . innerHTML + '</span>' )
101
+ }
102
+ } else {
103
+ // 如果链接上选区是特殊元素,需要获取最近的a标签,获取html结果,以保留特殊元素
104
+ const parentNodeA = getParentNodeA ( $selectedLink ) !
105
+
106
+ const selectionContent = parentNodeA . innerHTML
107
+
108
+ editor . cmd . do ( 'insertHTML' , '<span>' + selectionContent + '</span>' )
109
+ }
84
110
}
85
111
86
112
/**
@@ -143,6 +169,10 @@ export default function (editor: Editor, text: string, link: string): PanelConf
143
169
selector : '#' + btnOkId ,
144
170
type : 'click' ,
145
171
fn : ( ) => {
172
+ // 获取链接区间的顶层元素
173
+ const $selectionContainerElem = editor . selection . getSelectionContainerElem ( ) !
174
+ const $elem = $selectionContainerElem ?. elems [ 0 ]
175
+
146
176
// 获取选取
147
177
editor . selection . restoreSelection ( )
148
178
const topNode = editor . selection
@@ -181,6 +211,34 @@ export default function (editor: Editor, text: string, link: string): PanelConf
181
211
if ( ! text ) text = link
182
212
// 校验链接是否满足用户的规则,若不满足则不插入
183
213
if ( ! checkLink ( text , link ) ) return
214
+
215
+ /**
216
+ * 插入链接
217
+ * 1、针对首次插入链接,利用选区插入a标签即可
218
+ * 1、针对:<a><b>xxxx</b></a> 情况,用户操作修改或者替换链接时,编辑得到a,修改已有a标签的href
219
+ * 2、针对:<b><a>xxxx</a></b> 情况, 用户操作修改或者替换链接时,只要修改已有a标签的href
220
+ */
221
+
222
+ // 选区范围是a标签,直接替换href链接即可
223
+ if ( $elem ?. nodeName === 'A' ) {
224
+ $elem . setAttribute ( 'href' , link )
225
+
226
+ return true
227
+ }
228
+
229
+ // 不是a标签,并且为特殊元素, 需要检查是不是首次设置链接,还是已经设置过链接。
230
+ if ( $elem ?. nodeName !== 'A' && EXTRA_TAG . includes ( $elem . nodeName ) ) {
231
+ const nodeA = getParentNodeA ( $selectionContainerElem )
232
+
233
+ // 防止第一次设置就为特殊元素,这种情况应该为首次设置链接
234
+ if ( nodeA ) {
235
+ nodeA . setAttribute ( 'href' , link )
236
+
237
+ return true
238
+ }
239
+ }
240
+
241
+ // 首次插入链接
184
242
insertLink ( text , link )
185
243
186
244
// 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭
0 commit comments