mirror of
https://github.com/discourse/discourse.git
synced 2025-09-07 12:02:53 +08:00
Add cursor tests, fix algorithm and extract method.
This commit is contained in:
parent
ba2db48dbb
commit
43c1dd82f6
2 changed files with 129 additions and 26 deletions
|
@ -534,34 +534,48 @@ export default Ember.Component.extend({
|
|||
|
||||
const textarea = this.$('textarea.d-editor-input')[0];
|
||||
|
||||
// Remember cursor/selection.
|
||||
const selectionStart = textarea.selectionStart;
|
||||
const selectionEnd = textarea.selectionEnd;
|
||||
const needleEnd = needleStart + oldVal.length;
|
||||
const replacementEnd = needleStart + newVal.length;
|
||||
// Determine post-replace selection.
|
||||
const newSelection = this._determinePostReplaceSelection({
|
||||
selection: { start: textarea.selectionStart, end: textarea.selectionEnd },
|
||||
needle: { start: needleStart, end: needleStart + oldVal.length },
|
||||
replacement: { start: needleStart, end: needleStart + newVal.length }
|
||||
});
|
||||
|
||||
// Replace value (side effect: cursor at end).
|
||||
// Replace value (side effect: cursor at the end).
|
||||
this.set('value', val.replace(oldVal, newVal));
|
||||
|
||||
// Determine cursor/selection.
|
||||
let newSelectionStart, newSelectionEnd;
|
||||
if (selectionEnd <= needleEnd) {
|
||||
// Selection before needle.
|
||||
newSelectionStart = selectionStart;
|
||||
newSelectionEnd = selectionEnd;
|
||||
} else if (selectionStart < needleEnd) {
|
||||
// Selection within needle.
|
||||
newSelectionStart = replacementEnd;
|
||||
newSelectionEnd = replacementEnd;
|
||||
} else {
|
||||
// Selection behind needle.
|
||||
const lengthDiff = replacementEnd - needleStart;
|
||||
newSelectionStart = selectionStart + lengthDiff;
|
||||
newSelectionEnd = selectionEnd + lengthDiff;
|
||||
}
|
||||
|
||||
// Restore cursor.
|
||||
this._selectText(newSelectionStart, newSelectionEnd - newSelectionStart);
|
||||
this._selectText(newSelection.start, newSelection.end - newSelection.start);
|
||||
},
|
||||
|
||||
_determinePostReplaceSelection({ selection, needle, replacement }) {
|
||||
const diff = (replacement.end - replacement.start) - (needle.end - needle.start);
|
||||
|
||||
if (selection.end <= needle.start) {
|
||||
// Selection ends (and starts) before needle.
|
||||
return { start: selection.start, end: selection.end };
|
||||
} else if (selection.start <= needle.start) {
|
||||
// Selection starts before needle...
|
||||
if (selection.end < needle.end) {
|
||||
// ... and ends inside needle.
|
||||
return { start: selection.start, end: needle.start };
|
||||
} else {
|
||||
// ... and spans needle completely.
|
||||
return { start: selection.start, end: selection.end + diff };
|
||||
}
|
||||
} else if (selection.start < needle.end) {
|
||||
// Selection starts inside needle...
|
||||
if (selection.end <= needle.end) {
|
||||
// ... and ends inside needle.
|
||||
return { start: replacement.end, end: replacement.end };
|
||||
} else {
|
||||
// ... and spans end of needle.
|
||||
return { start: replacement.end, end: selection.end + diff };
|
||||
}
|
||||
} else {
|
||||
// Selection starts (and ends) behind needle.
|
||||
return { start: selection.start + diff, end: selection.end + diff };
|
||||
}
|
||||
},
|
||||
|
||||
_addText(sel, text) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue