Skip to content

Commit 3756762

Browse files
authored
Merge pull request #6241 from nextcloud-libraries/fix/4821/pasted-text
fix(NcRichContenteditable): fix pasted text handling
2 parents 52ccc29 + 6267b67 commit 3756762

File tree

1 file changed

+5
-77
lines changed

1 file changed

+5
-77
lines changed

src/components/NcRichContenteditable/NcRichContenteditable.vue

Lines changed: 5 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,6 @@ export default {
267267
@input="onInput"
268268
@compositionstart="isComposing = true"
269269
@compositionend="isComposing = false"
270-
@keydown.delete="onDelete"
271270
@keydown.esc.capture="onKeyEsc"
272271
@keydown.enter.exact="onEnter"
273272
@keydown.ctrl.enter.exact.stop.prevent="onCtrlEnter"
@@ -484,15 +483,6 @@ export default {
484483
return !this.localValue || this.localValue.trim() === ''
485484
},
486485
487-
/**
488-
* Is this Firefox? 🙄
489-
*
490-
* @return {boolean}
491-
*/
492-
isFF() {
493-
return !!navigator.userAgent.match(/firefox/i)
494-
},
495-
496486
/**
497487
* Is the current value over maxlength?
498488
*
@@ -792,23 +782,13 @@ export default {
792782
const text = clipboardData.getData('text')
793783
const selection = window.getSelection()
794784
795-
// If no selection, replace the whole data
796-
if (!selection.rangeCount) {
797-
this.updateValue(text)
798-
return
799-
}
800-
801785
// Generate text and insert
802786
const range = selection.getRangeAt(0)
803-
selection.deleteFromDocument()
787+
range.deleteContents()
804788
range.insertNode(document.createTextNode(text))
805789
806-
// Put cursor at the end of the selection
807-
const newRange = document.createRange()
808-
newRange.setStart(event.target, range.endOffset)
809-
newRange.collapse(true)
810-
selection.removeAllRanges()
811-
selection.addRange(newRange)
790+
// Collapse the range to the end position
791+
range.collapse(false)
812792
813793
// Propagate data
814794
this.updateValue(this.$refs.contenteditable.innerHTML)
@@ -820,7 +800,8 @@ export default {
820800
* @param {string} htmlOrText the html content (or raw text with @mentions)
821801
*/
822802
updateValue(htmlOrText) {
823-
const text = this.parseContent(htmlOrText)
803+
// Browsers keep <br> after erasing contenteditable
804+
const text = this.parseContent(htmlOrText).replace(/^\n$/, '')
824805
this.localValue = text
825806
this.model = text
826807
},
@@ -836,59 +817,6 @@ export default {
836817
this.localValue = value
837818
},
838819
839-
/**
840-
* Because FF have a decade old bug preventing contenteditable=false
841-
* to properly be deleted on backspace, we have to hack 👀
842-
* https://stackoverflow.com/a/59383394/3885878
843-
* https://stackoverflow.com/a/30574622
844-
*
845-
* @param {Event} event the delete keydown event
846-
*/
847-
onDelete(event) {
848-
if (!this.isFF || !window.getSelection) {
849-
return
850-
}
851-
852-
// Either disabled or edit deactivated
853-
if (!this.canEdit) {
854-
return
855-
}
856-
857-
// fix backspace bug in FF
858-
// https://bugzilla.mozilla.org/show_bug.cgi?id=685445
859-
// https://bugzilla.mozilla.org/show_bug.cgi?id=1665167
860-
const selection = window.getSelection()
861-
const node = event.target
862-
if (!selection.isCollapsed || !selection.rangeCount) {
863-
return
864-
}
865-
866-
const curRange = selection.getRangeAt(selection.rangeCount - 1)
867-
if (curRange.commonAncestorContainer.nodeType === 3 && curRange.startOffset > 0) {
868-
// we are in child selection. The characters of the text node is being deleted
869-
return
870-
}
871-
872-
const range = document.createRange()
873-
if (selection.anchorNode !== node) {
874-
// selection is in character mode. expand it to the whole editable field
875-
range.selectNodeContents(node)
876-
range.setEndBefore(selection.anchorNode)
877-
} else if (selection.anchorOffset > 0) {
878-
range.setEnd(node, selection.anchorOffset)
879-
} else {
880-
// reached the beginning of editable field
881-
return
882-
}
883-
range.setStart(node, range.endOffset - 1)
884-
885-
const previousNode = range.cloneContents().lastChild
886-
if (previousNode && previousNode.contentEditable === 'false') {
887-
// this is some rich content, e.g. smile. We should help the user to delete it
888-
range.deleteContents()
889-
event.preventDefault()
890-
}
891-
},
892820
/**
893821
* Enter key pressed. Submits if not multiline
894822
*

0 commit comments

Comments
 (0)