UNPKG

matrix-react-sdk

Version:
87 lines (78 loc) 10.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isCaretAtEnd = isCaretAtEnd; exports.isCaretAtStart = isCaretAtStart; exports.isSelectionEmpty = isSelectionEmpty; exports.setSelection = setSelection; /* Copyright 2024 New Vector Ltd. Copyright 2022 The Matrix.org Foundation C.I.C. SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ function setSelection(selection) { if (selection.anchorNode && selection.focusNode) { const range = new Range(); if (selection.isForward) { range.setStart(selection.anchorNode, selection.anchorOffset); range.setEnd(selection.focusNode, selection.focusOffset); } else { range.setStart(selection.focusNode, selection.focusOffset); range.setEnd(selection.anchorNode, selection.anchorOffset); } document.getSelection()?.removeAllRanges(); document.getSelection()?.addRange(range); } // Waiting for the next loop to ensure that the selection is effective return new Promise(resolve => setTimeout(resolve, 0)); } function isSelectionEmpty() { const selection = document.getSelection(); return Boolean(selection?.isCollapsed); } function isCaretAtStart(editor) { const selection = document.getSelection(); // No selection or the caret is not at the beginning of the selected element if (!selection) { return false; } // When we are pressing keyboard up in an empty main composer, the selection is on the editor with an anchorOffset at O or 1 (yes, this is strange) const isOnFirstElement = selection.anchorNode === editor && selection.anchorOffset <= 1; if (isOnFirstElement) { return true; } // In case of nested html elements (list, code blocks), we are going through all the first child let child = editor.firstChild; do { if (child === selection.anchorNode) { return selection.anchorOffset === 0; } } while (child = child?.firstChild || null); return false; } function isCaretAtEnd(editor) { const selection = document.getSelection(); if (!selection) { return false; } // When we are cycling across all the timeline message with the keyboard // The caret is on the last text element but focusNode and anchorNode refers to the editor div // In this case, the focusOffset & anchorOffset match the index + 1 of the selected text const isOnLastElement = selection.focusNode === editor && selection.focusOffset === editor.childNodes?.length; if (isOnLastElement) { return true; } // In case of nested html elements (list, code blocks), we are going through all the last child // The last child of the editor is always a <br> tag, we skip it let child = editor.childNodes.item(editor.childNodes.length - 2); do { if (child === selection.focusNode) { // Checking that the cursor is at end of the selected text return selection.focusOffset === child.textContent?.length; } } while (child = child.lastChild); return false; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJzZXRTZWxlY3Rpb24iLCJzZWxlY3Rpb24iLCJhbmNob3JOb2RlIiwiZm9jdXNOb2RlIiwicmFuZ2UiLCJSYW5nZSIsImlzRm9yd2FyZCIsInNldFN0YXJ0IiwiYW5jaG9yT2Zmc2V0Iiwic2V0RW5kIiwiZm9jdXNPZmZzZXQiLCJkb2N1bWVudCIsImdldFNlbGVjdGlvbiIsInJlbW92ZUFsbFJhbmdlcyIsImFkZFJhbmdlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJzZXRUaW1lb3V0IiwiaXNTZWxlY3Rpb25FbXB0eSIsIkJvb2xlYW4iLCJpc0NvbGxhcHNlZCIsImlzQ2FyZXRBdFN0YXJ0IiwiZWRpdG9yIiwiaXNPbkZpcnN0RWxlbWVudCIsImNoaWxkIiwiZmlyc3RDaGlsZCIsImlzQ2FyZXRBdEVuZCIsImlzT25MYXN0RWxlbWVudCIsImNoaWxkTm9kZXMiLCJsZW5ndGgiLCJpdGVtIiwidGV4dENvbnRlbnQiLCJsYXN0Q2hpbGQiXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy92aWV3cy9yb29tcy93eXNpd3lnX2NvbXBvc2VyL3V0aWxzL3NlbGVjdGlvbi50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuQ29weXJpZ2h0IDIwMjQgTmV3IFZlY3RvciBMdGQuXG5Db3B5cmlnaHQgMjAyMiBUaGUgTWF0cml4Lm9yZyBGb3VuZGF0aW9uIEMuSS5DLlxuXG5TUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQUdQTC0zLjAtb25seSBPUiBHUEwtMy4wLW9ubHlcblBsZWFzZSBzZWUgTElDRU5TRSBmaWxlcyBpbiB0aGUgcmVwb3NpdG9yeSByb290IGZvciBmdWxsIGRldGFpbHMuXG4qL1xuXG5pbXBvcnQgeyBTdWJTZWxlY3Rpb24gfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIHNldFNlbGVjdGlvbihzZWxlY3Rpb246IFN1YlNlbGVjdGlvbik6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmIChzZWxlY3Rpb24uYW5jaG9yTm9kZSAmJiBzZWxlY3Rpb24uZm9jdXNOb2RlKSB7XG4gICAgICAgIGNvbnN0IHJhbmdlID0gbmV3IFJhbmdlKCk7XG5cbiAgICAgICAgaWYgKHNlbGVjdGlvbi5pc0ZvcndhcmQpIHtcbiAgICAgICAgICAgIHJhbmdlLnNldFN0YXJ0KHNlbGVjdGlvbi5hbmNob3JOb2RlLCBzZWxlY3Rpb24uYW5jaG9yT2Zmc2V0KTtcbiAgICAgICAgICAgIHJhbmdlLnNldEVuZChzZWxlY3Rpb24uZm9jdXNOb2RlLCBzZWxlY3Rpb24uZm9jdXNPZmZzZXQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmFuZ2Uuc2V0U3RhcnQoc2VsZWN0aW9uLmZvY3VzTm9kZSwgc2VsZWN0aW9uLmZvY3VzT2Zmc2V0KTtcbiAgICAgICAgICAgIHJhbmdlLnNldEVuZChzZWxlY3Rpb24uYW5jaG9yTm9kZSwgc2VsZWN0aW9uLmFuY2hvck9mZnNldCk7XG4gICAgICAgIH1cbiAgICAgICAgZG9jdW1lbnQuZ2V0U2VsZWN0aW9uKCk/LnJlbW92ZUFsbFJhbmdlcygpO1xuICAgICAgICBkb2N1bWVudC5nZXRTZWxlY3Rpb24oKT8uYWRkUmFuZ2UocmFuZ2UpO1xuICAgIH1cblxuICAgIC8vIFdhaXRpbmcgZm9yIHRoZSBuZXh0IGxvb3AgdG8gZW5zdXJlIHRoYXQgdGhlIHNlbGVjdGlvbiBpcyBlZmZlY3RpdmVcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgMCkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNTZWxlY3Rpb25FbXB0eSgpOiBib29sZWFuIHtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSBkb2N1bWVudC5nZXRTZWxlY3Rpb24oKTtcbiAgICByZXR1cm4gQm9vbGVhbihzZWxlY3Rpb24/LmlzQ29sbGFwc2VkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzQ2FyZXRBdFN0YXJ0KGVkaXRvcjogSFRNTEVsZW1lbnQpOiBib29sZWFuIHtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSBkb2N1bWVudC5nZXRTZWxlY3Rpb24oKTtcblxuICAgIC8vIE5vIHNlbGVjdGlvbiBvciB0aGUgY2FyZXQgaXMgbm90IGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHNlbGVjdGVkIGVsZW1lbnRcbiAgICBpZiAoIXNlbGVjdGlvbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gV2hlbiB3ZSBhcmUgcHJlc3Npbmcga2V5Ym9hcmQgdXAgaW4gYW4gZW1wdHkgbWFpbiBjb21wb3NlciwgdGhlIHNlbGVjdGlvbiBpcyBvbiB0aGUgZWRpdG9yIHdpdGggYW4gYW5jaG9yT2Zmc2V0IGF0IE8gb3IgMSAoeWVzLCB0aGlzIGlzIHN0cmFuZ2UpXG4gICAgY29uc3QgaXNPbkZpcnN0RWxlbWVudCA9IHNlbGVjdGlvbi5hbmNob3JOb2RlID09PSBlZGl0b3IgJiYgc2VsZWN0aW9uLmFuY2hvck9mZnNldCA8PSAxO1xuICAgIGlmIChpc09uRmlyc3RFbGVtZW50KSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8vIEluIGNhc2Ugb2YgbmVzdGVkIGh0bWwgZWxlbWVudHMgKGxpc3QsIGNvZGUgYmxvY2tzKSwgd2UgYXJlIGdvaW5nIHRocm91Z2ggYWxsIHRoZSBmaXJzdCBjaGlsZFxuICAgIGxldCBjaGlsZCA9IGVkaXRvci5maXJzdENoaWxkO1xuICAgIGRvIHtcbiAgICAgICAgaWYgKGNoaWxkID09PSBzZWxlY3Rpb24uYW5jaG9yTm9kZSkge1xuICAgICAgICAgICAgcmV0dXJuIHNlbGVjdGlvbi5hbmNob3JPZmZzZXQgPT09IDA7XG4gICAgICAgIH1cbiAgICB9IHdoaWxlICgoY2hpbGQgPSBjaGlsZD8uZmlyc3RDaGlsZCB8fCBudWxsKSk7XG5cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0NhcmV0QXRFbmQoZWRpdG9yOiBIVE1MRWxlbWVudCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHNlbGVjdGlvbiA9IGRvY3VtZW50LmdldFNlbGVjdGlvbigpO1xuXG4gICAgaWYgKCFzZWxlY3Rpb24pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIFdoZW4gd2UgYXJlIGN5Y2xpbmcgYWNyb3NzIGFsbCB0aGUgdGltZWxpbmUgbWVzc2FnZSB3aXRoIHRoZSBrZXlib2FyZFxuICAgIC8vIFRoZSBjYXJldCBpcyBvbiB0aGUgbGFzdCB0ZXh0IGVsZW1lbnQgYnV0IGZvY3VzTm9kZSBhbmQgYW5jaG9yTm9kZSByZWZlcnMgdG8gdGhlIGVkaXRvciBkaXZcbiAgICAvLyBJbiB0aGlzIGNhc2UsIHRoZSBmb2N1c09mZnNldCAmIGFuY2hvck9mZnNldCBtYXRjaCB0aGUgaW5kZXggKyAxIG9mIHRoZSBzZWxlY3RlZCB0ZXh0XG4gICAgY29uc3QgaXNPbkxhc3RFbGVtZW50ID0gc2VsZWN0aW9uLmZvY3VzTm9kZSA9PT0gZWRpdG9yICYmIHNlbGVjdGlvbi5mb2N1c09mZnNldCA9PT0gZWRpdG9yLmNoaWxkTm9kZXM/Lmxlbmd0aDtcbiAgICBpZiAoaXNPbkxhc3RFbGVtZW50KSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8vIEluIGNhc2Ugb2YgbmVzdGVkIGh0bWwgZWxlbWVudHMgKGxpc3QsIGNvZGUgYmxvY2tzKSwgd2UgYXJlIGdvaW5nIHRocm91Z2ggYWxsIHRoZSBsYXN0IGNoaWxkXG4gICAgLy8gVGhlIGxhc3QgY2hpbGQgb2YgdGhlIGVkaXRvciBpcyBhbHdheXMgYSA8YnI+IHRhZywgd2Ugc2tpcCBpdFxuICAgIGxldCBjaGlsZDogQ2hpbGROb2RlIHwgbnVsbCA9IGVkaXRvci5jaGlsZE5vZGVzLml0ZW0oZWRpdG9yLmNoaWxkTm9kZXMubGVuZ3RoIC0gMik7XG4gICAgZG8ge1xuICAgICAgICBpZiAoY2hpbGQgPT09IHNlbGVjdGlvbi5mb2N1c05vZGUpIHtcbiAgICAgICAgICAgIC8vIENoZWNraW5nIHRoYXQgdGhlIGN1cnNvciBpcyBhdCBlbmQgb2YgdGhlIHNlbGVjdGVkIHRleHRcbiAgICAgICAgICAgIHJldHVybiBzZWxlY3Rpb24uZm9jdXNPZmZzZXQgPT09IGNoaWxkLnRleHRDb250ZW50Py5sZW5ndGg7XG4gICAgICAgIH1cbiAgICB9IHdoaWxlICgoY2hpbGQgPSBjaGlsZC5sYXN0Q2hpbGQpKTtcblxuICAgIHJldHVybiBmYWxzZTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBSU8sU0FBU0EsWUFBWUEsQ0FBQ0MsU0FBdUIsRUFBaUI7RUFDakUsSUFBSUEsU0FBUyxDQUFDQyxVQUFVLElBQUlELFNBQVMsQ0FBQ0UsU0FBUyxFQUFFO0lBQzdDLE1BQU1DLEtBQUssR0FBRyxJQUFJQyxLQUFLLENBQUMsQ0FBQztJQUV6QixJQUFJSixTQUFTLENBQUNLLFNBQVMsRUFBRTtNQUNyQkYsS0FBSyxDQUFDRyxRQUFRLENBQUNOLFNBQVMsQ0FBQ0MsVUFBVSxFQUFFRCxTQUFTLENBQUNPLFlBQVksQ0FBQztNQUM1REosS0FBSyxDQUFDSyxNQUFNLENBQUNSLFNBQVMsQ0FBQ0UsU0FBUyxFQUFFRixTQUFTLENBQUNTLFdBQVcsQ0FBQztJQUM1RCxDQUFDLE1BQU07TUFDSE4sS0FBSyxDQUFDRyxRQUFRLENBQUNOLFNBQVMsQ0FBQ0UsU0FBUyxFQUFFRixTQUFTLENBQUNTLFdBQVcsQ0FBQztNQUMxRE4sS0FBSyxDQUFDSyxNQUFNLENBQUNSLFNBQVMsQ0FBQ0MsVUFBVSxFQUFFRCxTQUFTLENBQUNPLFlBQVksQ0FBQztJQUM5RDtJQUNBRyxRQUFRLENBQUNDLFlBQVksQ0FBQyxDQUFDLEVBQUVDLGVBQWUsQ0FBQyxDQUFDO0lBQzFDRixRQUFRLENBQUNDLFlBQVksQ0FBQyxDQUFDLEVBQUVFLFFBQVEsQ0FBQ1YsS0FBSyxDQUFDO0VBQzVDOztFQUVBO0VBQ0EsT0FBTyxJQUFJVyxPQUFPLENBQUVDLE9BQU8sSUFBS0MsVUFBVSxDQUFDRCxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDM0Q7QUFFTyxTQUFTRSxnQkFBZ0JBLENBQUEsRUFBWTtFQUN4QyxNQUFNakIsU0FBUyxHQUFHVSxRQUFRLENBQUNDLFlBQVksQ0FBQyxDQUFDO0VBQ3pDLE9BQU9PLE9BQU8sQ0FBQ2xCLFNBQVMsRUFBRW1CLFdBQVcsQ0FBQztBQUMxQztBQUVPLFNBQVNDLGNBQWNBLENBQUNDLE1BQW1CLEVBQVc7RUFDekQsTUFBTXJCLFNBQVMsR0FBR1UsUUFBUSxDQUFDQyxZQUFZLENBQUMsQ0FBQzs7RUFFekM7RUFDQSxJQUFJLENBQUNYLFNBQVMsRUFBRTtJQUNaLE9BQU8sS0FBSztFQUNoQjs7RUFFQTtFQUNBLE1BQU1zQixnQkFBZ0IsR0FBR3RCLFNBQVMsQ0FBQ0MsVUFBVSxLQUFLb0IsTUFBTSxJQUFJckIsU0FBUyxDQUFDTyxZQUFZLElBQUksQ0FBQztFQUN2RixJQUFJZSxnQkFBZ0IsRUFBRTtJQUNsQixPQUFPLElBQUk7RUFDZjs7RUFFQTtFQUNBLElBQUlDLEtBQUssR0FBR0YsTUFBTSxDQUFDRyxVQUFVO0VBQzdCLEdBQUc7SUFDQyxJQUFJRCxLQUFLLEtBQUt2QixTQUFTLENBQUNDLFVBQVUsRUFBRTtNQUNoQyxPQUFPRCxTQUFTLENBQUNPLFlBQVksS0FBSyxDQUFDO0lBQ3ZDO0VBQ0osQ0FBQyxRQUFTZ0IsS0FBSyxHQUFHQSxLQUFLLEVBQUVDLFVBQVUsSUFBSSxJQUFJO0VBRTNDLE9BQU8sS0FBSztBQUNoQjtBQUVPLFNBQVNDLFlBQVlBLENBQUNKLE1BQW1CLEVBQVc7RUFDdkQsTUFBTXJCLFNBQVMsR0FBR1UsUUFBUSxDQUFDQyxZQUFZLENBQUMsQ0FBQztFQUV6QyxJQUFJLENBQUNYLFNBQVMsRUFBRTtJQUNaLE9BQU8sS0FBSztFQUNoQjs7RUFFQTtFQUNBO0VBQ0E7RUFDQSxNQUFNMEIsZUFBZSxHQUFHMUIsU0FBUyxDQUFDRSxTQUFTLEtBQUttQixNQUFNLElBQUlyQixTQUFTLENBQUNTLFdBQVcsS0FBS1ksTUFBTSxDQUFDTSxVQUFVLEVBQUVDLE1BQU07RUFDN0csSUFBSUYsZUFBZSxFQUFFO0lBQ2pCLE9BQU8sSUFBSTtFQUNmOztFQUVBO0VBQ0E7RUFDQSxJQUFJSCxLQUF1QixHQUFHRixNQUFNLENBQUNNLFVBQVUsQ0FBQ0UsSUFBSSxDQUFDUixNQUFNLENBQUNNLFVBQVUsQ0FBQ0MsTUFBTSxHQUFHLENBQUMsQ0FBQztFQUNsRixHQUFHO0lBQ0MsSUFBSUwsS0FBSyxLQUFLdkIsU0FBUyxDQUFDRSxTQUFTLEVBQUU7TUFDL0I7TUFDQSxPQUFPRixTQUFTLENBQUNTLFdBQVcsS0FBS2MsS0FBSyxDQUFDTyxXQUFXLEVBQUVGLE1BQU07SUFDOUQ7RUFDSixDQUFDLFFBQVNMLEtBQUssR0FBR0EsS0FBSyxDQUFDUSxTQUFTO0VBRWpDLE9BQU8sS0FBSztBQUNoQiIsImlnbm9yZUxpc3QiOltdfQ==