- insertClipboardImages(images) {
- const cursorPos = this.editor.cm.coordsChar({left: event.pageX, top: event.pageY});
- this.editor.cm.setCursor(cursorPos);
- for (const image of images) {
- this.uploadImage(image);
+ #cleanTextForEditor(text) {
+ return text.replace(/\r\n|\r/g, '\n');
+ }
+
+ /**
+ * Find and replace the first occurrence of [search] with [replace]
+ * @param {String} search
+ * @param {String} replace
+ */
+ #findAndReplaceContent(search, replace) {
+ const newText = this.#getText().replace(search, replace);
+ this.#setText(newText);
+ }
+
+ /**
+ * Wrap the line in the given start and end contents.
+ * @param {String} start
+ * @param {String} end
+ */
+ #wrapLine(start, end) {
+ const selectionRange = this.#getSelectionRange();
+ const line = this.editor.cm.state.doc.lineAt(selectionRange.from);
+ const lineContent = line.text;
+ let newLineContent;
+ let lineOffset = 0;
+
+ if (lineContent.startsWith(start) && lineContent.endsWith(end)) {
+ newLineContent = lineContent.slice(start.length, lineContent.length - end.length);
+ lineOffset = -(start.length);
+ } else {
+ newLineContent = `${start}${lineContent}${end}`;
+ lineOffset = start.length;
+ }
+
+ this.#dispatchChange(line.from, line.to, newLineContent, selectionRange.from + lineOffset);
+ }
+
+ /**
+ * Dispatch changes to the editor.
+ * @param {Number} from
+ * @param {?Number} to
+ * @param {?String} text
+ * @param {?Number} selectFrom
+ * @param {?Number} selectTo
+ */
+ #dispatchChange(from, to = null, text = null, selectFrom = null, selectTo = null) {
+ const tr = {changes: {from, to, insert: text}};
+
+ if (selectFrom) {
+ tr.selection = {anchor: selectFrom};
+ if (selectTo) {
+ tr.selection.head = selectTo;
+ }