mirror of
https://github.com/discourse/discourse.git
synced 2026-09-05 04:40:41 -05:00
Merge pull request #4630 from caugner/feature-preserve-cursor-in-editor-upload
FEATURE: Preserve cursor in editor upload
This commit is contained in:
@@ -12,6 +12,7 @@ import { emojiSearch } from 'pretty-text/emoji';
|
||||
import { emojiUrlFor } from 'discourse/lib/text';
|
||||
import { getRegister } from 'discourse-common/lib/get-owner';
|
||||
import { findRawTemplate } from 'discourse/lib/raw-templates';
|
||||
import { determinePostReplaceSelection } from 'discourse/lib/utilities';
|
||||
import deprecated from 'discourse-common/lib/deprecated';
|
||||
|
||||
// Our head can be a static string or a function that returns a string
|
||||
@@ -525,11 +526,27 @@ export default Ember.Component.extend({
|
||||
|
||||
_replaceText(oldVal, newVal) {
|
||||
const val = this.get('value');
|
||||
const loc = val.indexOf(oldVal);
|
||||
if (loc !== -1) {
|
||||
this.set('value', val.replace(oldVal, newVal));
|
||||
this._selectText(loc + newVal.length, 0);
|
||||
const needleStart = val.indexOf(oldVal);
|
||||
|
||||
if (needleStart === -1) {
|
||||
// Nothing to replace.
|
||||
return;
|
||||
}
|
||||
|
||||
const textarea = this.$('textarea.d-editor-input')[0];
|
||||
|
||||
// Determine post-replace selection.
|
||||
const newSelection = 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 the end).
|
||||
this.set('value', val.replace(oldVal, newVal));
|
||||
|
||||
// Restore cursor.
|
||||
this._selectText(newSelection.start, newSelection.end - newSelection.start);
|
||||
},
|
||||
|
||||
_addText(sel, text) {
|
||||
|
||||
@@ -300,5 +300,35 @@ export function defaultHomepage() {
|
||||
return Discourse.SiteSettings.top_menu.split("|")[0].split(",")[0];
|
||||
}
|
||||
|
||||
export function 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 };
|
||||
}
|
||||
}
|
||||
|
||||
// This prevents a mini racer crash
|
||||
export default {};
|
||||
|
||||
Reference in New Issue
Block a user