diff --git a/app/assets/javascripts/discourse/components/d-editor.js.es6 b/app/assets/javascripts/discourse/components/d-editor.js.es6 index 97fd9b2074f..d5228324966 100644 --- a/app/assets/javascripts/discourse/components/d-editor.js.es6 +++ b/app/assets/javascripts/discourse/components/d-editor.js.es6 @@ -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 @@ -535,7 +536,7 @@ export default Ember.Component.extend({ const textarea = this.$('textarea.d-editor-input')[0]; // Determine post-replace selection. - const newSelection = this._determinePostReplaceSelection({ + const newSelection = determinePostReplaceSelection({ selection: { start: textarea.selectionStart, end: textarea.selectionEnd }, needle: { start: needleStart, end: needleStart + oldVal.length }, replacement: { start: needleStart, end: needleStart + newVal.length } @@ -548,36 +549,6 @@ export default Ember.Component.extend({ 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) { const $textarea = this.$('textarea.d-editor-input'); const insert = `${sel.pre}${text}`; diff --git a/app/assets/javascripts/discourse/lib/utilities.js.es6 b/app/assets/javascripts/discourse/lib/utilities.js.es6 index fcf67375273..27b55bbdd74 100644 --- a/app/assets/javascripts/discourse/lib/utilities.js.es6 +++ b/app/assets/javascripts/discourse/lib/utilities.js.es6 @@ -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 {};