matrix-react-sdk
Version:
SDK for matrix.org using React
87 lines (78 loc) • 10.8 kB
JavaScript
;
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==