fix(wysiwyg): Fix text selection detection for formatting menu in Shadow DOM

- Update selection detection to properly handle Shadow DOM boundaries
- Use getComposedRanges API correctly according to MDN documentation
- Add direct selection detection within block components
- Dispatch custom events from blocks when text is selected
- Fix formatting menu positioning using selection rect from events
This commit is contained in:
Juergen Kunz
2025-06-24 16:17:00 +00:00
parent ca525ce7e3
commit 3b93bd63a7
5 changed files with 320 additions and 110 deletions

View File

@ -143,11 +143,9 @@ export class WysiwygFormatting {
}
}
static getSelectionCoordinates(shadowRoot?: ShadowRoot): { x: number, y: number } | null {
static getSelectionCoordinates(...shadowRoots: ShadowRoot[]): { x: number, y: number } | null {
// Get selection info using the new utility that handles Shadow DOM
const selectionInfo = shadowRoot
? WysiwygSelection.getSelectionInfo(shadowRoot)
: WysiwygSelection.getSelectionInfo();
const selectionInfo = WysiwygSelection.getSelectionInfo(...shadowRoots);
console.log('getSelectionCoordinates - selectionInfo:', selectionInfo);
@ -162,8 +160,29 @@ export class WysiwygFormatting {
console.log('Range rect:', rect);
if (rect.width === 0) {
console.log('Rect width is 0');
if (rect.width === 0 && rect.height === 0) {
console.log('Rect width and height are 0, trying different approach');
// Sometimes the rect is collapsed, let's try getting the caret position
if ('caretPositionFromPoint' in document) {
const selection = window.getSelection();
if (selection && selection.rangeCount > 0) {
const range = selection.getRangeAt(0);
const tempSpan = document.createElement('span');
tempSpan.textContent = '\u200B'; // Zero-width space
range.insertNode(tempSpan);
const spanRect = tempSpan.getBoundingClientRect();
tempSpan.remove();
if (spanRect.width > 0 || spanRect.height > 0) {
const coords = {
x: spanRect.left,
y: Math.max(45, spanRect.top - 45)
};
console.log('Used span trick for coords:', coords);
return coords;
}
}
}
return null;
}