Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/editor/extensions/editor_markdown_ext.js')
-rw-r--r--app/assets/javascripts/editor/extensions/editor_markdown_ext.js97
1 files changed, 97 insertions, 0 deletions
diff --git a/app/assets/javascripts/editor/extensions/editor_markdown_ext.js b/app/assets/javascripts/editor/extensions/editor_markdown_ext.js
new file mode 100644
index 00000000000..2ce003753f7
--- /dev/null
+++ b/app/assets/javascripts/editor/extensions/editor_markdown_ext.js
@@ -0,0 +1,97 @@
+import { EditorLiteExtension } from './editor_lite_extension_base';
+
+export class EditorMarkdownExtension extends EditorLiteExtension {
+ getSelectedText(selection = this.getSelection()) {
+ const { startLineNumber, endLineNumber, startColumn, endColumn } = selection;
+ const valArray = this.getValue().split('\n');
+ let text = '';
+ if (startLineNumber === endLineNumber) {
+ text = valArray[startLineNumber - 1].slice(startColumn - 1, endColumn - 1);
+ } else {
+ const startLineText = valArray[startLineNumber - 1].slice(startColumn - 1);
+ const endLineText = valArray[endLineNumber - 1].slice(0, endColumn - 1);
+
+ for (let i = startLineNumber, k = endLineNumber - 1; i < k; i += 1) {
+ text += `${valArray[i]}`;
+ if (i !== k - 1) text += `\n`;
+ }
+ text = text
+ ? [startLineText, text, endLineText].join('\n')
+ : [startLineText, endLineText].join('\n');
+ }
+ return text;
+ }
+
+ replaceSelectedText(text, select = undefined) {
+ const forceMoveMarkers = !select;
+ this.executeEdits('', [{ range: this.getSelection(), text, forceMoveMarkers }]);
+ }
+
+ moveCursor(dx = 0, dy = 0) {
+ const pos = this.getPosition();
+ pos.column += dx;
+ pos.lineNumber += dy;
+ this.setPosition(pos);
+ }
+
+ /**
+ * Adjust existing selection to select text within the original selection.
+ * - If `selectedText` is not supplied, we fetch selected text with
+ *
+ * ALGORITHM:
+ *
+ * MULTI-LINE SELECTION
+ * 1. Find line that contains `toSelect` text.
+ * 2. Using the index of this line and the position of `toSelect` text in it,
+ * construct:
+ * * newStartLineNumber
+ * * newStartColumn
+ *
+ * SINGLE-LINE SELECTION
+ * 1. Use `startLineNumber` from the current selection as `newStartLineNumber`
+ * 2. Find the position of `toSelect` text in it to get `newStartColumn`
+ *
+ * 3. `newEndLineNumber` — Since this method is supposed to be used with
+ * markdown decorators that are pretty short, the `newEndLineNumber` is
+ * suggested to be assumed the same as the startLine.
+ * 4. `newEndColumn` — pretty obvious
+ * 5. Adjust the start and end positions of the current selection
+ * 6. Re-set selection on the instance
+ *
+ * @param {string} toSelect - New text to select within current selection.
+ * @param {string} selectedText - Currently selected text. It's just a
+ * shortcut: If it's not supplied, we fetch selected text from the instance
+ */
+ selectWithinSelection(toSelect, selectedText) {
+ const currentSelection = this.getSelection();
+ if (currentSelection.isEmpty() || !toSelect) {
+ return;
+ }
+ const text = selectedText || this.getSelectedText(currentSelection);
+ let lineShift;
+ let newStartLineNumber;
+ let newStartColumn;
+
+ const textLines = text.split('\n');
+
+ if (textLines.length > 1) {
+ // Multi-line selection
+ lineShift = textLines.findIndex((line) => line.indexOf(toSelect) !== -1);
+ newStartLineNumber = currentSelection.startLineNumber + lineShift;
+ newStartColumn = textLines[lineShift].indexOf(toSelect) + 1;
+ } else {
+ // Single-line selection
+ newStartLineNumber = currentSelection.startLineNumber;
+ newStartColumn = currentSelection.startColumn + text.indexOf(toSelect);
+ }
+
+ const newEndLineNumber = newStartLineNumber;
+ const newEndColumn = newStartColumn + toSelect.length;
+
+ const newSelection = currentSelection
+ .setStartPosition(newStartLineNumber, newStartColumn)
+ .setEndPosition(newEndLineNumber, newEndColumn);
+
+ this.setSelection(newSelection);
+ }
+}