Skip to content

Commit f32972b

Browse files
fix: pasting over a selection behaviour
Delete all the markups whose text is completely within the current selection
1 parent c384d69 commit f32972b

File tree

4 files changed

+34
-6
lines changed

4 files changed

+34
-6
lines changed

src/clipboard.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ export function paste (element, cursor, clipboardContent) {
2929
const document = element.ownerDocument
3030
element.setAttribute(config.pastingAttribute, true)
3131

32-
if (cursor.isSelection) cursor = cursor.deleteContent()
32+
if (cursor.isSelection) {
33+
cursor = cursor.deleteExactSurroundingMarkups()
34+
.deleteContainedMarkupTags()
35+
.deleteContent()
36+
}
3337

3438
// Create a placeholder to help parse HTML
3539
const pasteHolder = document.createElement('div')

src/content.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,12 @@ export function getInnerTags (range, filterFunc) {
244244
return range.getNodes([nodeType.elementNode], filterFunc)
245245
}
246246

247+
// Get all tags whose text is completely within the current selection.
248+
export function getContainedTags (range, filterFunc) {
249+
return range.getNodes([nodeType.elementNode], filterFunc)
250+
.filter(elem => range.containsNodeText(elem))
251+
}
252+
247253
// Transform an array of elements into an array
248254
// of tagnames in uppercase
249255
//

src/cursor.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ export default class Cursor {
6969
return content.getInnerTags(this.range, filterFunc)
7070
}
7171

72+
// Get all tags whose text is completely within the current selection.
73+
getContainedTags (filterFunc) {
74+
return content.getContainedTags(this.range, filterFunc)
75+
}
76+
7277
// Get all tags that surround the current selection.
7378
getAncestorTags (filterFunc) {
7479
return content.getAncestorTags(this.host, this.range, filterFunc)

src/selection.js

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -246,24 +246,37 @@ export default class Selection extends Cursor {
246246
}
247247

248248
// Delete the farest ancestor that is an exact selection
249+
//
250+
// @return Selection instance
249251
deleteExactSurroundingMarkups () {
250-
const markupTags = this.getAncestorTags(
252+
const ancestorMarkupTags = this.getAncestorTags(
251253
(elem) => ['STRONG', 'EM'].includes(elem.nodeName)
252254
).reverse()
253-
for (const markupTag of markupTags) {
254-
if (this.isExactSelection(markupTag)) {
255-
markupTag.remove()
255+
for (const ancestorMarkupTag of ancestorMarkupTags) {
256+
if (this.isExactSelection(ancestorMarkupTag)) {
257+
ancestorMarkupTag.remove()
256258
break
257259
}
258260
}
261+
return new Selection(this.host, this.range)
262+
}
263+
264+
// Delete all the markups whose text is completely within the current selection.
265+
//
266+
// @return Selection instance
267+
deleteContainedMarkupTags () {
268+
const containedMarkupTags = this.getContainedTags(
269+
(elem) => ['STRONG', 'EM'].includes(elem.nodeName)
270+
)
271+
containedMarkupTags.forEach(containedMarkupTag => containedMarkupTag.remove())
272+
return new Selection(this.host, this.range)
259273
}
260274

261275
// Delete the contents inside the range and exact surrounding markups.
262276
// After that the selection will be a cursor.
263277
//
264278
// @return Cursor instance
265279
deleteContent () {
266-
this.deleteExactSurroundingMarkups()
267280
this.range.deleteContents()
268281
return new Cursor(this.host, this.range)
269282
}

0 commit comments

Comments
 (0)