This commit is contained in:
Juergen Kunz
2025-06-24 23:46:52 +00:00
parent 474385a939
commit 5f86fdba72
8 changed files with 89 additions and 18 deletions

View File

@ -25,7 +25,7 @@ export class CodeBlockHandler extends BaseBlockHandler {
data-block-id="${block.id}"
data-block-type="${block.type}"
spellcheck="false"
>${block.content || ''}</div>
></div>
</div>
`;
}

View File

@ -32,7 +32,7 @@ export class HeadingBlockHandler extends BaseBlockHandler {
data-placeholder="${placeholder}"
data-block-id="${block.id}"
data-block-type="${block.type}"
>${block.content || ''}</div>
></div>
`;
}

View File

@ -25,7 +25,7 @@ export class ParagraphBlockHandler extends BaseBlockHandler {
data-placeholder="${placeholder}"
data-block-id="${block.id}"
data-block-type="${block.type}"
>${block.content || ''}</div>
></div>
`;
}

View File

@ -25,7 +25,7 @@ export class QuoteBlockHandler extends BaseBlockHandler {
data-placeholder="${placeholder}"
data-block-id="${block.id}"
data-block-type="${block.type}"
>${block.content || ''}</div>
></div>
`;
}

View File

@ -1196,6 +1196,12 @@ export class DeesWysiwygBlock extends DeesElement {
}
public focusWithCursor(position: 'start' | 'end' | number = 'end'): void {
console.log('focusWithCursor called', {
blockId: this.block?.id,
blockType: this.block?.type,
position
});
// Check if we have a registered handler for this block type
const handler = BlockRegistry.getHandler(this.block.type);
if (handler && handler.focusWithCursor) {
@ -1389,9 +1395,10 @@ export class DeesWysiwygBlock extends DeesElement {
return handler.setCursorToStart(container, context);
}
// Always find the element fresh, don't rely on cached blockElement
const editableElement = this.block?.type === 'code'
? this.shadowRoot?.querySelector('.block.code') as HTMLDivElement
: this.blockElement;
: this.shadowRoot?.querySelector('.block') as HTMLDivElement;
if (editableElement) {
WysiwygBlocks.setCursorToStart(editableElement);
}
@ -1406,9 +1413,10 @@ export class DeesWysiwygBlock extends DeesElement {
return handler.setCursorToEnd(container, context);
}
// Always find the element fresh, don't rely on cached blockElement
const editableElement = this.block?.type === 'code'
? this.shadowRoot?.querySelector('.block.code') as HTMLDivElement
: this.blockElement;
: this.shadowRoot?.querySelector('.block') as HTMLDivElement;
if (editableElement) {
WysiwygBlocks.setCursorToEnd(editableElement);
}

View File

@ -306,6 +306,19 @@ export class WysiwygKeyboardHandler {
const cursorPos = WysiwygSelection.getCursorPositionInElement(target, ...shadowRoots);
const actualContent = blockComponent.getContent ? blockComponent.getContent() : target.textContent;
console.log('Backspace handler cursor position:', {
blockId: block.id,
storedBlockContent: block.content,
actualDOMContent: actualContent,
targetTextContent: target.textContent,
cursorPos,
isAtBeginning: cursorPos === 0,
isStoredEmpty: block.content === '',
isActuallyEmpty: actualContent === '' || actualContent.trim() === ''
});
// Check if cursor is at the beginning of the block
if (cursorPos === 0) {
e.preventDefault();
@ -335,7 +348,8 @@ export class WysiwygKeyboardHandler {
if (block.type === 'code' && prevBlock.type !== 'code') {
// Can't merge code into non-code block
if (block.content === '') {
const actualContent = blockComponent.getContent ? blockComponent.getContent() : block.content;
if (actualContent === '' || actualContent.trim() === '') {
blockOps.removeBlock(block.id);
await blockOps.focusBlock(prevBlock.id, 'end');
}
@ -376,16 +390,21 @@ export class WysiwygKeyboardHandler {
// Focus previous block at merge point
await blockOps.focusBlock(prevBlock.id, mergePoint);
}
} else if (block.content === '' && this.component.blocks.length > 1) {
// Empty block - just remove it
e.preventDefault();
const prevBlock = blockOps.getPreviousBlock(block.id);
} else if (this.component.blocks.length > 1) {
// Check if block is actually empty by getting current content from DOM
const currentContent = blockComponent.getContent ? blockComponent.getContent() : block.content;
if (prevBlock) {
blockOps.removeBlock(block.id);
if (currentContent === '' || currentContent.trim() === '') {
// Empty block - just remove it
e.preventDefault();
const prevBlock = blockOps.getPreviousBlock(block.id);
if (prevBlock.type !== 'divider') {
await blockOps.focusBlock(prevBlock.id, 'end');
if (prevBlock) {
blockOps.removeBlock(block.id);
if (prevBlock.type !== 'divider') {
await blockOps.focusBlock(prevBlock.id, 'end');
}
}
}
}
@ -655,7 +674,14 @@ export class WysiwygKeyboardHandler {
if (prevBlock) {
e.preventDefault();
const nonEditableTypes = ['divider', 'image', 'youtube', 'markdown', 'html', 'attachment'];
await blockOps.focusBlock(prevBlock.id, nonEditableTypes.includes(prevBlock.type) ? undefined : 'end');
const position = nonEditableTypes.includes(prevBlock.type) ? undefined : 'end';
console.log('ArrowLeft: Navigating to previous block', {
currentBlockId: block.id,
prevBlockId: prevBlock.id,
prevBlockType: prevBlock.type,
focusPosition: position
});
await blockOps.focusBlock(prevBlock.id, position);
}
}
// Otherwise, let the browser handle normal left arrow navigation

View File

@ -122,9 +122,24 @@ export class WysiwygSelection {
range.selectNodeContents(element);
// Handle case where selection is in a text node that's a child of the element
if (element.contains(selectionInfo.startContainer)) {
// Use our Shadow DOM-aware contains method
const isContained = this.containsAcrossShadowDOM(element, selectionInfo.startContainer);
console.log('getCursorPositionInElement debug:', {
element: element.tagName,
elementText: element.textContent,
selectionContainer: selectionInfo.startContainer,
selectionOffset: selectionInfo.startOffset,
isContained,
elementShadowRoot: element.getRootNode(),
selectionShadowRoot: selectionInfo.startContainer.getRootNode()
});
if (isContained) {
range.setEnd(selectionInfo.startContainer, selectionInfo.startOffset);
return range.toString().length;
const position = range.toString().length;
console.log('Cursor position calculated:', position);
return position;
} else {
// Selection might be in shadow DOM or different context
// Try to find the equivalent position in the element
@ -133,8 +148,10 @@ export class WysiwygSelection {
// If the selection is at the beginning or end, handle those cases
if (selectionInfo.startOffset === 0) {
console.log('Fallback: returning 0 (beginning)');
return 0;
} else if (selectionInfo.startOffset === selectionText.length) {
console.log('Fallback: returning text length:', text.length);
return text.length;
}