Move cursor/selection algo to lib/utilities.

This commit is contained in:
Claas Augner 2016-12-29 10:16:17 +01:00
parent 37386faff2
commit 2e9bbccea9
No known key found for this signature in database
GPG Key ID: 63E8BCF5EB1A35AE
2 changed files with 32 additions and 31 deletions

View File

@ -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}`;

View File

@ -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 {};