@lobehub/editor
Version:
A powerful and extensible rich text editor built on Meta's Lexical framework, providing a modern editing experience with React integration.
68 lines (67 loc) • 2.96 kB
JavaScript
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var VERTICAL_GAP = 4;
var HORIZONTAL_OFFSET = 0;
function getScrollParent(element) {
var parent = element.parentElement;
while (parent) {
var _window$getComputedSt = window.getComputedStyle(parent),
overflow = _window$getComputedSt.overflow,
overflowY = _window$getComputedSt.overflowY,
overflowX = _window$getComputedSt.overflowX;
if (/(auto|scroll)/.test(overflow + overflowY + overflowX)) {
return parent;
}
parent = parent.parentElement;
}
return document.documentElement;
}
export function setFloatingElemPosition(targetRect, floatingElem, anchorElem) {
var isLink = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
var verticalGap = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : VERTICAL_GAP;
var horizontalOffset = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : HORIZONTAL_OFFSET;
var scrollerElem = getScrollParent(anchorElem);
if (targetRect === null || !scrollerElem) {
floatingElem.style.opacity = '0';
floatingElem.style.transform = 'translate(-10000px, -10000px)';
return;
}
var floatingElemRect = floatingElem.getBoundingClientRect();
var anchorElementRect = anchorElem.getBoundingClientRect();
var editorScrollerRect = scrollerElem.getBoundingClientRect();
var top = targetRect.top - floatingElemRect.height - verticalGap;
var left = targetRect.left - horizontalOffset;
// Check if text is end-aligned
var selection = window.getSelection();
if (selection && selection.rangeCount > 0) {
var range = selection.getRangeAt(0);
var textNode = range.startContainer;
if (textNode.nodeType === Node.ELEMENT_NODE || textNode.parentElement) {
var textElement = textNode.nodeType === Node.ELEMENT_NODE ? textNode : textNode.parentElement;
var textAlign = window.getComputedStyle(textElement).textAlign;
if (textAlign === 'right' || textAlign === 'end') {
// For end-aligned text, position the toolbar relative to the text end
left = targetRect.right - floatingElemRect.width + horizontalOffset;
}
}
}
if (top < editorScrollerRect.top) {
// adjusted height for link element if the element is at top
top += floatingElemRect.height + targetRect.height + verticalGap * (isLink ? 9 : 2);
}
if (left + floatingElemRect.width > editorScrollerRect.right) {
left = editorScrollerRect.right - floatingElemRect.width - horizontalOffset;
}
if (left < editorScrollerRect.left) {
left = editorScrollerRect.left + horizontalOffset;
}
top -= anchorElementRect.top + 12;
left -= anchorElementRect.left;
floatingElem.style.opacity = '1';
floatingElem.style.transform = "translate(".concat(left, "px, ").concat(top, "px)");
}