fix(dees-modal): theming
This commit is contained in:
@@ -7,7 +7,8 @@ export class WysiwygBlocks {
|
||||
const items = content.split('\n').filter(item => item.trim());
|
||||
if (items.length === 0) return '';
|
||||
const listTag = metadata?.listType === 'ordered' ? 'ol' : 'ul';
|
||||
return `<${listTag}>${items.map(item => `<li>${WysiwygConverters.escapeHtml(item)}</li>`).join('')}</${listTag}>`;
|
||||
// Don't escape HTML to preserve formatting
|
||||
return `<${listTag}>${items.map(item => `<li>${item}</li>`).join('')}</${listTag}>`;
|
||||
}
|
||||
|
||||
static renderBlock(
|
||||
@@ -102,21 +103,88 @@ export class WysiwygBlocks {
|
||||
}
|
||||
|
||||
static setCursorToEnd(element: HTMLElement): void {
|
||||
const range = document.createRange();
|
||||
const sel = window.getSelection();
|
||||
range.selectNodeContents(element);
|
||||
range.collapse(false);
|
||||
sel!.removeAllRanges();
|
||||
sel!.addRange(range);
|
||||
if (!sel) return;
|
||||
|
||||
const range = document.createRange();
|
||||
|
||||
// Handle different content types
|
||||
if (element.childNodes.length === 0) {
|
||||
// Empty element - add a zero-width space to enable cursor
|
||||
const textNode = document.createTextNode('\u200B');
|
||||
element.appendChild(textNode);
|
||||
range.setStart(textNode, 1);
|
||||
range.collapse(true);
|
||||
} else {
|
||||
// Find the last text node or element
|
||||
const lastNode = this.getLastNode(element);
|
||||
if (lastNode.nodeType === Node.TEXT_NODE) {
|
||||
range.setStart(lastNode, lastNode.textContent?.length || 0);
|
||||
} else {
|
||||
range.setStartAfter(lastNode);
|
||||
}
|
||||
range.collapse(true);
|
||||
}
|
||||
|
||||
sel.removeAllRanges();
|
||||
sel.addRange(range);
|
||||
|
||||
// Remove zero-width space if it was added
|
||||
if (element.textContent === '\u200B') {
|
||||
element.textContent = '';
|
||||
}
|
||||
}
|
||||
|
||||
static setCursorToStart(element: HTMLElement): void {
|
||||
const range = document.createRange();
|
||||
const sel = window.getSelection();
|
||||
range.selectNodeContents(element);
|
||||
range.collapse(true);
|
||||
sel!.removeAllRanges();
|
||||
sel!.addRange(range);
|
||||
if (!sel) return;
|
||||
|
||||
const range = document.createRange();
|
||||
|
||||
// Handle different content types
|
||||
if (element.childNodes.length === 0) {
|
||||
// Empty element
|
||||
range.setStart(element, 0);
|
||||
range.collapse(true);
|
||||
} else {
|
||||
// Find the first text node or element
|
||||
const firstNode = this.getFirstNode(element);
|
||||
if (firstNode.nodeType === Node.TEXT_NODE) {
|
||||
range.setStart(firstNode, 0);
|
||||
} else {
|
||||
range.setStartBefore(firstNode);
|
||||
}
|
||||
range.collapse(true);
|
||||
}
|
||||
|
||||
sel.removeAllRanges();
|
||||
sel.addRange(range);
|
||||
}
|
||||
|
||||
private static getLastNode(element: Node): Node {
|
||||
if (element.childNodes.length === 0) {
|
||||
return element;
|
||||
}
|
||||
|
||||
const lastChild = element.childNodes[element.childNodes.length - 1];
|
||||
if (lastChild.nodeType === Node.TEXT_NODE || lastChild.childNodes.length === 0) {
|
||||
return lastChild;
|
||||
}
|
||||
|
||||
return this.getLastNode(lastChild);
|
||||
}
|
||||
|
||||
private static getFirstNode(element: Node): Node {
|
||||
if (element.childNodes.length === 0) {
|
||||
return element;
|
||||
}
|
||||
|
||||
const firstChild = element.childNodes[0];
|
||||
if (firstChild.nodeType === Node.TEXT_NODE || firstChild.childNodes.length === 0) {
|
||||
return firstChild;
|
||||
}
|
||||
|
||||
return this.getFirstNode(firstChild);
|
||||
}
|
||||
|
||||
static focusListItem(listElement: HTMLElement): void {
|
||||
|
Reference in New Issue
Block a user