in app/assets/javascripts/lib/utils/text_markdown.js [434:593]
export function insertMarkdownText({
textArea,
text,
tag,
cursorOffset,
blockTag,
selected = '',
wrap,
select,
editor,
}) {
// If we aren't really inserting anything, let's just noop.
// Let's check for `selected` too because there might be hidden logic that actually
// is expected to run for this case.
if (!tag && !blockTag && !selected) {
return;
}
selected = selectSurroundingTags(textArea, tag) ?? selected;
let removedLastNewLine = false;
let removedFirstNewLine = false;
let currentLineEmpty = false;
const selectedLength = selected.length;
const { selectionStart: textAreaSelectionStart, selectionEnd: textAreaSelectionEnd } =
textArea || {};
let editorSelectionStart;
let editorSelectionEnd;
let lastNewLine;
let textToUpdate;
selected = selected.toString();
if (editor) {
const selectionRange = getEditorSelectionRange(editor);
editorSelectionStart = selectionRange.start;
editorSelectionEnd = selectionRange.end;
}
// check for link pattern and selected text is an URL
// if so fill in the url part instead of the text part of the pattern.
if (tag === LINK_TAG_PATTERN) {
if (isValidURL(selected)) {
tag = '[text]({text})';
select = 'text';
}
}
// Remove the first newline
if (selected.indexOf('\n') === 0) {
removedFirstNewLine = true;
selected = selected.replace(/\n+/, '');
}
// Remove the last newline
if (textArea) {
if (textArea.selectionEnd - textArea.selectionStart > selected.replace(/\n$/, '').length) {
removedLastNewLine = true;
selected = selected.replace(/\n$/, '');
}
} else if (editor) {
if (editorSelectionStart.row !== editorSelectionEnd.row) {
removedLastNewLine = true;
selected = selected.replace(/\n$/, '');
}
}
const selectedSplit = selected.split('\n');
if (editor && !wrap) {
lastNewLine = editor.getValue().split('\n')[editorSelectionStart.row];
if (/^\s*$/.test(lastNewLine)) {
currentLineEmpty = true;
}
} else if (textArea && !wrap) {
lastNewLine = textArea.value.substr(0, textArea.selectionStart).lastIndexOf('\n');
// Check whether the current line is empty or consists only of spaces(=handle as empty)
if (/^\s*$/.test(textArea.value.substring(lastNewLine, textArea.selectionStart))) {
currentLineEmpty = true;
}
}
const isBeginning =
(textArea && textArea.selectionStart === 0) ||
(editor && editorSelectionStart.column === 0 && editorSelectionStart.row === 0);
const startChar = !wrap && !currentLineEmpty && !isBeginning ? '\n' : '';
const textPlaceholder = '{text}';
const {
shouldUseSelectedWithoutTags,
removeTagFromLine,
shouldRemoveTagFromLine,
getSelectedWithoutTags,
shouldPreserveTextAreaSelection,
} = prepareInsertMarkdownText({ selected, tag, selectedSplit });
const getSelectedWithTags = () => `${startChar}${tag}${selected}${wrap ? tag : ''}`;
if (selectedSplit.length > 1 && (!wrap || (blockTag != null && blockTag !== ''))) {
if (blockTag != null && blockTag !== '') {
textToUpdate = editor
? editorBlockTagText(text, blockTag, selected, editor)
: blockTagText(text, textArea, blockTag, selected);
} else {
textToUpdate = selectedSplit
.map((line) => {
if (tag.indexOf(textPlaceholder) > -1) {
return tag.replace(textPlaceholder, line);
}
if (shouldRemoveTagFromLine(line)) {
return removeTagFromLine(line);
}
return String(tag) + line;
})
.join('\n');
}
} else if (tag.indexOf(textPlaceholder) > -1) {
textToUpdate = tag.replace(textPlaceholder, () =>
selected.replace(/\\n/g, '\n').replace(/%br/g, '\\n'),
);
} else if (shouldUseSelectedWithoutTags) {
textToUpdate = getSelectedWithoutTags();
} else {
textToUpdate = getSelectedWithTags();
}
if (removedFirstNewLine) {
textToUpdate = `\n${textToUpdate}`;
}
if (removedLastNewLine) {
textToUpdate += '\n';
}
if (editor) {
editor.replaceSelectedText(textToUpdate, select);
} else {
insertText(textArea, textToUpdate);
}
if (shouldPreserveTextAreaSelection) {
const offset = textToUpdate.length - selectedLength;
textArea.setSelectionRange(textAreaSelectionStart, textAreaSelectionEnd + offset);
} else {
moveCursor({
textArea,
tag: tag.replace(textPlaceholder, selected),
cursorOffset,
positionBetweenTags: wrap && selected.length === 0,
removedLastNewLine,
select,
editor,
editorSelectionStart,
editorSelectionEnd,
});
}
}